JuzPost Accounts API

Connected social accounts and the named groups that bundle them.

GitHub OpenAPI

Operations 3

GET /accounts List your connected social accounts #
GET /groups List the named account groups you can schedule to #
GET /groups/{groupId} Get one account group and its members #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/juzpost:juzpost-accounts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

juzpost-accounts-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: JuzPost REST Accounts API
  version: 1.0.0
  summary: Token-only API behind the `juzpost` command line client.
  description: 'The machine-facing surface of JuzPost: connect-once device login, draft creation,

    media upload to R2, and scheduling posts across connected social accounts.


    **Base URL.** `https://www.juzpost.com/api/cli/v1`. Note the `cli` segment:

    `/api/v1` is a different, older surface used by the dashboard and is not this API.


    **Authentication.** Every operation requires `Authorization: Bearer `. There are no

    unauthenticated operations.


    ## Get a token


    1. Open **Settings, General** in the JuzPost

    dashboard.

    2. Find the **API keys** card and choose **Generate API key**.

    3. Copy the key. It begins with `jp_live_` and is shown **once**, at creation. Store it in

    your secret manager before leaving the page.

    4. Check it works:


    ```bash

    curl https://www.juzpost.com/api/cli/v1/me \

    --header "Authorization: Bearer jp_live_YOUR_KEY"

    ```


    A `200` comes back with your account, plan and capabilities. A `401` means the key is

    wrong, revoked, or was pasted with a trailing newline.


    Revoke a key from the same card. Nothing in this API can delete the credential it is

    calling with, which is deliberate: an automated client should not be able to lock itself

    out, and revocation should be a human action.


    **One token, one account.** A token belongs to exactly one JuzPost account (a *workspace*).

    Every operation acts on that one account, and no operation anywhere accepts an account id.


    **Entitlements.** Every operation other than `GET /me` requires the

    caller''s plan to include the `api` capability, and `POST /schedule`,

    `POST /posts/{postId}/schedule` and `POST /storage/presign` additionally require `schedule`

    (or `publish`, for immediate posting). A plan that lacks the capability produces `402`,

    never `403`. Call `GET /me` first to check before attempting a write that is doomed.


    **Errors.** Every non-2xx response uses the same envelope: a single `error` object carrying

    a stable machine-readable `code`, a human `message`, and optional `details`. Never branch on

    the message text; branch on `error.code` or the HTTP status.


    **Unknown ids.** An id that is not yours is reported as `404`, never `403`, so no operation

    can be used to discover whether someone else''s data exists.'
  contact:
    name: JuzPost Support
    url: https://www.juzpost.com/support
  license:
    name: Proprietary
    url: https://www.juzpost.com/terms
servers:
- url: https://www.juzpost.com/api/cli/v1
  description: The only supported base URL.
security:
- bearerAuth: []
tags:
- name: Accounts
  description: Connected social accounts and the named groups that bundle them.
paths:
  /accounts:
    get:
      operationId: listAccounts
      summary: List your connected social accounts
      description: 'Returns connected social accounts, newest first by default. Use the returned `id` values

        as `socialAccountIds` when scheduling. Access and refresh tokens are never included in

        the response. Results are cursor-paginated: pass `pagination.nextCursor` back as

        `cursor` to get the next page, and stop when `pagination.hasMore` is false.'
      tags:
      - Accounts
      parameters:
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Order'
      - $ref: '#/components/parameters/AccountSort'
      - $ref: '#/components/parameters/PlatformFilter'
      - $ref: '#/components/parameters/GroupIdFilter'
      responses:
        '200':
          description: One page of connected accounts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountPage'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
  /groups:
    get:
      operationId: listGroups
      summary: List the named account groups you can schedule to
      description: 'Returns channel groups: saved bundles of social accounts, used so you can schedule to

        "all-tiktok" instead of listing account ids. The group `name` is what

        `POST /schedule` accepts in its `group` field. Cursor-paginated.'
      tags:
      - Accounts
      parameters:
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Order'
      - $ref: '#/components/parameters/GroupSort'
      - $ref: '#/components/parameters/NameFilter'
      responses:
        '200':
          description: One page of channel groups.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupPage'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
  /groups/{groupId}:
    get:
      operationId: getGroup
      summary: Get one account group and its members
      description: 'Returns a single channel group with the full list of social account ids in it. A group

        belonging to someone else is reported as `404`, never `403`.'
      tags:
      - Accounts
      parameters:
      - $ref: '#/components/parameters/GroupIdPath'
      responses:
        '200':
          description: The group and its member account ids.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/PaymentRequired'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  parameters:
    GroupIdPath:
      name: groupId
      in: path
      required: true
      description: Id of the channel group, as returned by `GET /groups`.
      schema:
        type: string
        format: uuid
    AccountSort:
      name: sort
      in: query
      required: false
      description: 'Which field to sort connected accounts by. An unlisted value returns `400`.

        '
      schema:
        type: string
        enum:
        - createdAt
        - username
        - platform
        default: createdAt
    Order:
      name: order
      in: query
      required: false
      description: 'Sort direction. Anything other than the literal `asc` is treated as `desc`.

        '
      schema:
        type: string
        enum:
        - asc
        - desc
        default: desc
    NameFilter:
      name: name
      in: query
      required: false
      description: Return only groups whose name contains this substring.
      schema:
        type: string
    GroupIdFilter:
      name: groupId
      in: query
      required: false
      description: 'Return only accounts that are members of this channel group. An unknown or empty group

        yields an empty page rather than an error.

        '
      schema:
        type: string
        format: uuid
    PlatformFilter:
      name: platform
      in: query
      required: false
      description: 'Return only accounts on this platform, matched exactly, for example `tiktok`,

        `youtube`, `instagram`, `x`, `bluesky`, `pinterest`.

        '
      schema:
        type: string
    Limit:
      name: limit
      in: query
      required: false
      description: 'How many items to return in this page. Values outside 1-100 are clamped rather than

        rejected. Defaults to 20.

        '
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    GroupSort:
      name: sort
      in: query
      required: false
      description: 'Which field to sort groups by. An unlisted value returns `400`.

        '
      schema:
        type: string
        enum:
        - createdAt
        - name
        default: createdAt
    Cursor:
      name: cursor
      in: query
      required: false
      description: 'Opaque continuation token. Omit it for the first page, then pass back the previous

        response''s `pagination.nextCursor` verbatim. Never parse, construct or modify it, and

        do not reuse a cursor after changing `sort`, `order` or any filter, which returns `400`

        with `error.details.code` of `invalid_cursor`.

        '
      schema:
        type: string
  schemas:
    GroupPage:
      allOf:
      - $ref: '#/components/schemas/PageEnvelope'
      - type: object
        description: A page of channel groups.
        properties:
          data:
            type: array
            description: The groups in this page.
            items:
              $ref: '#/components/schemas/Group'
    PaginationMeta:
      type: object
      description: 'Page state returned by every list operation. Keyset-based, so it stays correct while

        rows are being inserted, and it deliberately carries no total count.

        '
      required:
      - limit
      - nextCursor
      - hasMore
      properties:
        limit:
          type: integer
          description: The page size actually applied, after clamping to 1-100.
        nextCursor:
          type:
          - string
          - 'null'
          description: 'Pass this back as the `cursor` query parameter to fetch the next page. It is `null`

            when there is no next page.

            '
        hasMore:
          type: boolean
          description: 'True when at least one more page exists. Stop paginating when this is false rather

            than when the data array is short.

            '
    Account:
      type: object
      description: 'A connected social account. Access and refresh tokens are never serialized here.

        '
      required:
      - id
      - username
      - platform
      - avatarUrl
      - isActive
      - createdAt
      properties:
        id:
          type: string
          format: uuid
          description: 'The account id. Pass these values in `socialAccountIds` when scheduling.

            '
        username:
          type: string
          description: The handle or channel name on the platform.
        platform:
          type: string
          description: 'Which network this account is on, for example `tiktok`, `youtube`, `instagram`,

            `x`, `bluesky` or `pinterest`.

            '
        avatarUrl:
          type:
          - string
          - 'null'
          description: Profile picture URL, or null if the platform gave none.
        isActive:
          type: boolean
          description: 'Whether the connection is still usable. An inactive account normally needs

            reconnecting in the dashboard before it can publish.

            '
        createdAt:
          type: string
          format: date-time
          description: When the account was connected.
    Error:
      type: object
      description: 'The envelope returned by every non-2xx response in this API. There is never a top-level

        field other than `error`.

        '
      required:
      - error
      properties:
        error:
          type: object
          description: The single error describing why the request did not succeed.
          required:
          - code
          - message
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: 'Human-readable explanation, safe to show to a user. Wording is not stable across

                releases, so never parse or match on it.

                '
            details:
              description: 'Optional structured context whose shape depends on the code, for example

                `{ "requiredPlan": "pro" }` on a `payment_required`, `{ "code":

                "invalid_cursor" }` on a bad cursor, or `{ "usedBytes": …, "quotaBytes": … }`

                when a storage quota is full. Treat it as opaque unless a specific operation

                documents its contents.

                '
    Group:
      type: object
      description: 'A channel group: a named bundle of social accounts you can schedule to by name.

        '
      required:
      - id
      - name
      - accountIds
      - accountCount
      - createdAt
      properties:
        id:
          type: string
          format: uuid
          description: The group id.
        name:
          type: string
          description: 'The group''s name. This is the value `POST /schedule` accepts in its `group` field,

            matched exactly.

            '
        accountIds:
          type: array
          description: Ids of the social accounts in this group, in no guaranteed order.
          items:
            type: string
            format: uuid
            description: A social account id belonging to this group.
        accountCount:
          type: integer
          description: 'How many accounts are in the group. The bulk scheduler rejects groups of more than

            10 with a `422`.

            '
        createdAt:
          type: string
          format: date-time
          description: When the group was created.
    PageEnvelope:
      type: object
      description: 'Shared shape of every paginated response: a `data` array plus `pagination` state.

        '
      required:
      - data
      - pagination
      properties:
        data:
          type: array
          description: The rows in this page, ordered by the requested sort and direction.
          items: {}
        pagination:
          $ref: '#/components/schemas/PaginationMeta'
    ErrorCode:
      type: string
      description: 'Stable machine-readable error identifier. Branch on this rather than on the message.

        Each code maps to exactly one HTTP status.

        '
      enum:
      - bad_request
      - unauthorized
      - payment_required
      - forbidden
      - not_found
      - conflict
      - unprocessable
      - pending
      - rate_limited
      - internal
    AccountPage:
      allOf:
      - $ref: '#/components/schemas/PageEnvelope'
      - type: object
        description: A page of connected social accounts.
        properties:
          data:
            type: array
            description: The accounts in this page.
            items:
              $ref: '#/components/schemas/Account'
  responses:
    NotFound:
      description: 'No such resource. A resource that belongs to someone else is

        also reported here, so this never confirms whether another tenant''s id exists.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    PaymentRequired:
      description: 'The plan behind this token does not include the capability this operation needs.

        `error.details.requiredPlan` names the tier that does. This is never a token problem, so

        do not retry without changing the plan.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: 'The request body or query string failed validation. `error.message` names the first

        problem found.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: 'No bearer token was sent, or the token is unknown, revoked or malformed. Run the device

        login again to obtain a new token.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An API key created in the dashboard under Settings, General, API keys, sent as

        `Authorization: Bearer jp_live_...`. Required on every operation without exception.

        Missing, malformed, revoked or unknown tokens all produce `401` with code

        `unauthorized`.

        '