{
  "openapi": "3.0.3",
  "info": {
    "title": "Pulse partner API",
    "version": "1.0.0",
    "description": "Let your members connect LinkedIn, Instagram, Facebook and YouTube and post from your product. Replace the server URL with your Pulse address. Every error has the shape {\"error\":{\"code\",\"message\",\"field?\"}}. Each key can make 60 requests per minute (429 rate_limited with Retry-After); the hosted connect window is not counted. A request body can be 1 MB at most (413 body_too_large). A key is refused outside /v1/partner (403 forbidden_scope). Human-readable docs: /docs."
  },
  "servers": [
    {
      "url": "https://YOUR-PULSE-URL",
      "description": "Your Pulse address"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Members"
    },
    {
      "name": "Connect"
    },
    {
      "name": "Connections"
    },
    {
      "name": "Limits"
    },
    {
      "name": "Posts"
    }
  ],
  "paths": {
    "/v1/partner/members": {
      "post": {
        "summary": "Create a member (idempotent on external_id)",
        "tags": [
          "Members"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "createMember",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A member with this external_id already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json (the body is not a JSON object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "body_too_large (over 1 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "If a member with this external_id already exists you get 200 and that member (name and email in the repeat call are ignored). external_id: 1 to 128 characters. name: up to 120. email: must look like an address."
      },
      "get": {
        "summary": "List members",
        "tags": [
          "Members"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "listMembers",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Page size, 1 to 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "The next_cursor of the previous page. An unknown cursor is 422 validation."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "members",
                    "next_cursor"
                  ],
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Member"
                      }
                    },
                    "next_cursor": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation (bad limit or cursor)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Oldest first. next_cursor is null on the last page."
      }
    },
    "/v1/partner/members/{id}": {
      "get": {
        "summary": "Get a member",
        "tags": [
          "Members"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "getMember",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberWithConnections"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Returns the member and how many accounts they have connected."
      },
      "patch": {
        "summary": "Update a member",
        "tags": [
          "Members"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "updateMember",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Member"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json (the body is not a JSON object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "body_too_large (over 1 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Send only the fields to change. null clears name or email. external_id cannot be changed."
      },
      "delete": {
        "summary": "Delete a member",
        "tags": [
          "Members"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "deleteMember",
        "description": "Needs confirm=true (otherwise 400 confirm_required and nothing happens). In order: cancels the member's scheduled posts, disconnects every account, removes all posts and the member. If a post cannot be cancelled or an account cannot be disconnected the call returns 502 provider_unavailable and nothing is removed from Pulse (earlier steps may already have happened; call again). 409 conflict if a post is being prepared right now.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          },
          {
            "name": "confirm",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "true"
              ]
            },
            "description": "Must be exactly true."
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted"
          },
          "400": {
            "description": "confirm_required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict (a post is being prepared; retry in a few seconds)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/partner/members/{id}/connect-session": {
      "post": {
        "summary": "Create a connect session",
        "tags": [
          "Connect"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "createConnectSession",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectSessionCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectSession"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json (the body is not a JSON object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "limit_reached (every requested network is full)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "body_too_large (over 1 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation (return_url, expires_in, networks) or network_not_enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Returns the link of the hosted connect window. 409 limit_reached when no network in the session has room left. 422 network_not_enabled for a network that is not switched on for this member. The window works as a page, a popup or an iframe; it posts {type:'pulse.connection',member_id,network,status:'connected'|'disconnected'} to window.parent / window.opener after a change. The return_url Done button adds ?status=connected or ?status=cancelled. Expired link: 410 page. Changed link: 400 page. 120 window requests an hour per link."
      }
    },
    "/v1/partner/members/{id}/connections": {
      "get": {
        "summary": "List a member's connections",
        "tags": [
          "Connections"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "listConnections",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "connections"
                  ],
                  "properties": {
                    "connections": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Connection"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Also settles the member's accounts against the limits; an account that appeared with no room left is disconnected and not listed."
      }
    },
    "/v1/partner/members/{id}/connections/{cid}": {
      "delete": {
        "summary": "Disconnect one connection",
        "tags": [
          "Connections"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "deleteConnection",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          },
          {
            "name": "cid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Connection id (c_...)."
          }
        ],
        "responses": {
          "204": {
            "description": "Disconnected"
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Disconnects the account at the posting service. No confirm needed. If it cannot be disconnected: 502 provider_unavailable and the connection stays."
      }
    },
    "/v1/partner/members/{id}/limits": {
      "put": {
        "summary": "Set a member's limits",
        "tags": [
          "Limits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "setLimits",
        "description": "A field left out stays as it is; null clears it (falls back to the partner default, then the global default: max_accounts 10, max_per_network 3, all networks except X). A member's number can never exceed the partner default on your key: a higher number is refused with 422 validation (it is not reduced), a network outside the partner default with 422 network_not_enabled. Numbers are whole numbers from 1. Lowering does not disconnect existing accounts.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LimitsPut"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The limits now in force",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Limits"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json (the body is not a JSON object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "body_too_large (over 1 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation, or network_not_enabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/partner/members/{id}/posts": {
      "post": {
        "summary": "Create a post",
        "tags": [
          "Posts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "createPost",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json (the body is not a JSON object)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "body_too_large (over 1 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "validation, network_not_enabled, not_connected or ambiguous_account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "One account on a network is used automatically. Several accounts on a network and no connection_ids (or not exactly one named for that network): 422 ambiguous_account. A connection id that is not this member's: 404 not_found. A connection on a network not in networks: 422 validation. No working account on a listed network: 422 not_connected. A network outside the member's effective networks (X is off by default): 422 network_not_enabled. scheduled_at: in the past (one minute of slack) or more than a year ahead (366 days) is 422 validation. media_urls: up to 10 public https links, no IP addresses, localhost, internal names (.local .localhost .internal .lan .home .corp .intranet or no dot), credentials or ports other than 443, each up to 2048 characters."
      },
      "get": {
        "summary": "List posts",
        "tags": [
          "Posts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "listPosts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "posts"
                  ],
                  "properties": {
                    "posts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Post"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The 100 newest posts, newest first. No paging."
      }
    },
    "/v1/partner/members/{id}/posts/{pid}": {
      "get": {
        "summary": "Get a post",
        "tags": [
          "Posts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "getPost",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          },
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Post id."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Cancel a post before it goes out",
        "tags": [
          "Posts"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "operationId": "deletePost",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Member id."
          },
          {
            "name": "pid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Post id."
          }
        ],
        "responses": {
          "204": {
            "description": "Cancelled"
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found (the member, or the connection/post, does not exist or is not yours)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited. Wait the number of seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "provider_unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Only a post with status scheduled can be cancelled; otherwise 409 conflict (also 409 while the post is being prepared). 502 provider_unavailable if the cancel cannot be passed on; the post stays."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer fnk_..."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "confirm_required",
                  "invalid_json",
                  "unauthorized",
                  "forbidden_scope",
                  "not_found",
                  "conflict",
                  "limit_reached",
                  "body_too_large",
                  "validation",
                  "network_not_enabled",
                  "not_connected",
                  "ambiguous_account",
                  "rate_limited",
                  "internal",
                  "provider_unavailable"
                ]
              },
              "message": {
                "type": "string"
              },
              "field": {
                "type": "string",
                "description": "The input at fault, when there is one."
              }
            }
          }
        },
        "example": {
          "error": {
            "code": "ambiguous_account",
            "message": "This member has 2 LinkedIn accounts. Say which one with connection_ids.",
            "field": "networks"
          }
        }
      },
      "Limits": {
        "type": "object",
        "properties": {
          "max_accounts": {
            "type": "integer",
            "minimum": 1,
            "description": "Accounts across all networks."
          },
          "max_per_network": {
            "type": "integer",
            "minimum": 1,
            "description": "Accounts on any one network."
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "linkedin",
                "instagram",
                "facebook",
                "youtube",
                "x"
              ]
            },
            "description": "x appears only if switched on for your account."
          }
        },
        "example": {
          "max_accounts": 10,
          "max_per_network": 3,
          "networks": [
            "linkedin",
            "instagram",
            "facebook",
            "youtube"
          ]
        },
        "description": "The effective limits in force for a member: all three fields are always set.",
        "required": [
          "max_accounts",
          "max_per_network",
          "networks"
        ]
      },
      "LimitsPut": {
        "type": "object",
        "description": "All fields optional; omitted fields stay, null clears. A number cannot exceed the partner default on your key (422 validation); a network outside it is 422 network_not_enabled.",
        "properties": {
          "max_accounts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "nullable": true
          },
          "max_per_network": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "nullable": true
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "linkedin",
                "instagram",
                "facebook",
                "youtube",
                "x"
              ]
            },
            "nullable": true
          }
        }
      },
      "MemberCreate": {
        "type": "object",
        "required": [
          "external_id"
        ],
        "properties": {
          "external_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Your own id for this member."
          },
          "name": {
            "type": "string",
            "maxLength": 120,
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true,
            "maxLength": 254
          }
        }
      },
      "MemberPatch": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true,
            "maxLength": 254
          }
        }
      },
      "Member": {
        "type": "object",
        "required": [
          "id",
          "external_id",
          "created_at",
          "limits"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "m_ followed by 24 characters."
          },
          "external_id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-10-07T09:30:00.000Z"
          },
          "limits": {
            "$ref": "#/components/schemas/Limits"
          },
          "email": {
            "type": "string",
            "description": "Only present if you set one."
          }
        },
        "example": {
          "id": "m_4f9c2a71e0b35d8c6a1f9e24",
          "external_id": "user_8412",
          "name": "Amara Okafor",
          "created_at": "2026-10-07T09:30:00.000Z",
          "limits": {
            "max_accounts": 10,
            "max_per_network": 3,
            "networks": [
              "linkedin",
              "instagram",
              "facebook",
              "youtube"
            ]
          }
        }
      },
      "MemberWithConnections": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Member"
          },
          {
            "type": "object",
            "properties": {
              "connections": {
                "type": "integer",
                "description": "How many accounts the member has connected."
              }
            }
          }
        ]
      },
      "ConnectSessionCreate": {
        "type": "object",
        "properties": {
          "networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "linkedin",
                "instagram",
                "facebook",
                "youtube",
                "x"
              ]
            },
            "minItems": 1,
            "description": "Leave out for every network the member is allowed."
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "description": "A public https link (same rules as media_urls). Adds a Done button to the window that goes back with ?status=connected or ?status=cancelled.",
            "nullable": true
          },
          "expires_in": {
            "type": "integer",
            "minimum": 60,
            "maximum": 3600,
            "default": 1800
          }
        }
      },
      "ConnectSession": {
        "type": "object",
        "required": [
          "url",
          "expires_at"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "The connect window for this member. Works for one member only."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Connection": {
        "type": "object",
        "required": [
          "id",
          "network",
          "label",
          "status",
          "connected_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "c_..., opaque."
          },
          "network": {
            "type": "string",
            "enum": [
              "linkedin",
              "instagram",
              "facebook",
              "youtube",
              "x"
            ]
          },
          "label": {
            "type": "string",
            "description": "The account name, or the network's name if it has none."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "needs_reconnect"
            ],
            "description": "needs_reconnect: the member must sign in again (open a new connect session)."
          },
          "connected_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PostCreate": {
        "type": "object",
        "required": [
          "text",
          "networks"
        ],
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 20000,
            "minLength": 1
          },
          "media_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Up to 10 public https links: no IP addresses, localhost, internal names, credentials or ports other than 443.",
            "maxItems": 10
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "linkedin",
                "instagram",
                "facebook",
                "youtube",
                "x"
              ]
            },
            "minItems": 1,
            "description": "A network outside the member's effective networks is 422 network_not_enabled. Repeats are ignored."
          },
          "texts": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Per-network text, keyed by network. Only networks listed in networks are allowed. Each value up to 20000 characters."
          },
          "youtube_title": {
            "type": "string",
            "maxLength": 100,
            "description": "Up to 100 characters, no < or >."
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "description": "Omit to post in about 2 minutes. Not in the past (one minute of slack), at most 366 days ahead."
          },
          "connection_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Which account to use. One account on a network is used automatically; with several accounts on a network, name exactly one for it or get 422 ambiguous_account. Unknown id: 404 not_found."
          }
        }
      },
      "PostNetwork": {
        "type": "object",
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "linkedin",
              "instagram",
              "facebook",
              "youtube",
              "x"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "publishing",
              "published",
              "failed"
            ]
          },
          "external_url": {
            "type": "string",
            "nullable": true,
            "description": "Link to the live post once published."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "A plain sentence when this network failed."
          },
          "connection_id": {
            "type": "string",
            "nullable": true,
            "description": "The account (c_...) this network uses."
          }
        },
        "required": [
          "network",
          "connection_id",
          "status",
          "external_url",
          "error"
        ]
      },
      "Post": {
        "type": "object",
        "required": [
          "id",
          "status",
          "scheduled_at",
          "text",
          "networks"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "A UUID."
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "publishing",
              "published",
              "partial",
              "failed"
            ],
            "description": "partial: some networks published, some failed."
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "text": {
            "type": "string"
          },
          "networks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostNetwork"
            }
          },
          "error": {
            "type": "string",
            "description": "Only present when something went wrong with the post as a whole."
          }
        },
        "example": {
          "id": "5b0e8f1c-3a7d-4c52-9e64-0d2f7a91b8c3",
          "status": "scheduled",
          "scheduled_at": "2026-10-09T08:00:00.000Z",
          "text": "Our October workshop is open for booking.",
          "networks": [
            {
              "network": "linkedin",
              "connection_id": "c_66f1a2b3c4d5e6f708192a3b",
              "status": "scheduled",
              "external_url": null,
              "error": null
            }
          ]
        }
      }
    }
  }
}
