Hermoso AI Connect Links API

The connect-links API from Hermoso AI — 2 operation(s) for connect-links.

GitHub OpenAPI

Operations 3

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/hermoso-ai:hermoso-ai-connect-links-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

hermoso-ai-connect-links-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hermoso Ai Connect Links API
  version: '2026-08-26'
  description: 'Operations tagged connect-links across 2 of this provider''s published API definitions: app_hermoso_ai.json, app_hermoso_ai_rest.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://app.hermoso.ai
security:
- bearerAuth: []
tags:
- name: connect-links
paths:
  /v1/connect-links:
    post:
      operationId: createConnectLink
      summary: Create a connect link for your customer
      description: 'A short-lived hosted link that lets someone with NO Hermoso login connect their own account (Facebook and Instagram, Instagram, TikTok, YouTube, LinkedIn, X, Pinterest, Threads, Google Business Profile and the ad platforms) to the brand named by `X-Hermoso-User`. Hand `url` to your customer. They see a short page from Hermoso, accept Hermoso’s Terms and Privacy Policy, sign in on the platform’s own consent screen, and land on your `redirect_url` with `connect_status` (success | cancelled | error), `provider`, `brand`, `link_id`, `account`, `error_code` and your `state` added to its query string (a same-named parameter of yours is overwritten).


        THE PLATFORM’S CONSENT SCREEN SHOWS HERMOSO’S NAME, because the connection is made with Hermoso’s app on that platform.


        A link connects ONE provider to ONE brand. It can be retried after a cancel until it expires, and is spent once an account connects. Know when it connects from the `account.connected` webhook event (connect a webhook on the brand and include the `connections` group) or by polling GET /v1/connect-links/{id}. Facebook and LinkedIn then need the Pages chosen: call list_connector_accounts and set_connector_accounts through /v1/tools (the link’s creator owns that choice). Accounts that connect with a pasted key (Bluesky, Telegram) are connected with POST /v1/tools/connect_connector instead.'
      tags:
      - connect-links
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          type: string
        description: 'Send a unique value to make this call safe to retry. A replay returns the original response with `Idempotency-Replayed: true`, for 24 hours — except a call that queued a job, whose replay is that job as it is now (what `GET /v1/jobs/{id}` answers), so a finished render replays as done with its file.'
      - name: X-Hermoso-User
        in: header
        required: false
        schema:
          type: string
        description: 'Which profile to act on, when the account holds more than one: an `id` from `GET /v1/brands`. Defaults to the workspace the key is pinned to. Membership is re-authorised on every request, and an id this key cannot act on is a 404 `brand_not_found`, never an empty result.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConnectLinkCreate'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectLink'
        '400':
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, invalid or revoked key — or a channel that is not connected, in which case `error.connector` names it and `error.type` is `connector_error`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: '`error.code: brand_not_found`: `X-Hermoso-User` (or the profile this key is pinned to) names a profile this key cannot act on. `GET /v1/brands` lists the valid ids.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited. `Retry-After` says how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth: []
    servers:
    - url: https://app.hermoso.ai
  /v1/connect-links/{id}:
    get:
      operationId: getConnectLink
      summary: Retrieve a connect link
      description: '`status` is pending, opened, connected, cancelled, failed, expired or revoked. Once connected, `account` names what was connected. Kept for 7 days after the link expires.'
      tags:
      - connect-links
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: X-Hermoso-User
        in: header
        required: false
        schema:
          type: string
        description: 'Which profile to act on, when the account holds more than one: an `id` from `GET /v1/brands`. Defaults to the workspace the key is pinned to. Membership is re-authorised on every request, and an id this key cannot act on is a 404 `brand_not_found`, never an empty result.'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectLink'
        '400':
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, invalid or revoked key — or a channel that is not connected, in which case `error.connector` names it and `error.type` is `connector_error`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: '`error.code: brand_not_found`: `X-Hermoso-User` (or the profile this key is pinned to) names a profile this key cannot act on. `GET /v1/brands` lists the valid ids.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited. `Retry-After` says how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth: []
    delete:
      operationId: revokeConnectLink
      summary: Cancel a connect link
      description: The link stops working at once. A link that already connected an account cannot be revoked; remove that connection with DELETE /v1/connections/{provider}.
      tags:
      - connect-links
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: X-Hermoso-User
        in: header
        required: false
        schema:
          type: string
        description: 'Which profile to act on, when the account holds more than one: an `id` from `GET /v1/brands`. Defaults to the workspace the key is pinned to. Membership is re-authorised on every request, and an id this key cannot act on is a 404 `brand_not_found`, never an empty result.'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConnectLink'
        '400':
          description: Invalid request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, invalid or revoked key — or a channel that is not connected, in which case `error.connector` names it and `error.type` is `connector_error`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: '`error.code: brand_not_found`: `X-Hermoso-User` (or the profile this key is pinned to) names a profile this key cannot act on. `GET /v1/brands` lists the valid ids.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limited. `Retry-After` says how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth: []
    servers:
    - url: https://app.hermoso.ai
components:
  schemas:
    ConnectLinkCreate:
      type: object
      required:
      - provider
      properties:
        provider:
          type: string
          description: 'Which platform: meta (Facebook and Instagram), instagram (an Instagram account on its own login), tiktok, youtube, linkedin, linkedin_community (comments as a LinkedIn Page), x, pinterest, threads, google_business, and the ad platforms. An unsupported one is refused with the list.'
        redirect_url:
          type: string
          description: Where your customer lands afterwards. Must sit under a registered address (PUT /v1/connect-redirects). Omit to show them a plain “connected, you can close this window” page.
        state:
          type: string
          description: Your own value, up to 500 characters, returned on the redirect and in the webhook so you can match the connection to your customer.
        expires_in_minutes:
          type: integer
          minimum: 5
          maximum: 2880
          description: Default 60, at most 2880 (48 hours).
    ConnectLink:
      type: object
      properties:
        object:
          type: string
          enum:
          - connect_link
        id:
          type: string
        url:
          type: string
          description: Returned when the link is created. Hand it to your customer; it is a bearer link, so treat it like a password until it is used or expires.
        provider:
          type: string
        brand:
          type: string
        status:
          type: string
          enum:
          - pending
          - opened
          - connected
          - cancelled
          - failed
          - expired
          - revoked
        redirect_url:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        created_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        connected_at:
          type: string
          format: date-time
          nullable: true
        account:
          type: object
          nullable: true
          properties:
            label:
              type: string
              nullable: true
            handle:
              type: string
              nullable: true
            id:
              type: string
              nullable: true
        account_selection_required:
          type: boolean
          nullable: true
          description: 'True for Facebook/Instagram (meta) and LinkedIn: choose which Pages the brand may use with list_connector_accounts + set_connector_accounts before posting.'
        error:
          type: object
          nullable: true
          properties:
            code:
              type: string
            message:
              type: string
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - type
          - code
          - message
          properties:
            type:
              type: string
              enum:
              - authentication_error
              - permission_error
              - invalid_request_error
              - connector_error
              - rate_limit_error
              - insufficient_credits
              - api_error
              description: The coarse family — branch on this. New CODES land inside an existing type wherever possible so that branch keeps working; the enum is published for code generation, and a client should still fall through gracefully on a member it does not recognise.
            code:
              type: string
              description: The specific reason. Log this. New values may appear at any time.
            message:
              type: string
            param:
              type: string
              description: The offending field, when there is one.
            connector:
              type: string
              description: Present when the reason is a channel that is not connected. Reconnect in the app — an OAuth consent screen cannot be completed headlessly.
            credits_needed:
              type: number
              description: 'On `insufficient_credits` from a recast or an edit: what the request needs.'
            balance:
              type: number
              description: 'On `insufficient_credits` from a recast or an edit: what this workspace has.'
            unknown_arguments:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                    description: The key that was sent.
                  did_you_mean:
                    type: string
                    nullable: true
                    description: An argument THIS tool declares that the key most likely meant, or null.
              description: 'On `invalid_arguments` from POST /v1/tools/{name}: each key the tool does not take, with the argument it most likely meant. Nothing was run.'
            upgrade_url:
              type: string
              description: 'On `real_face_needs_paid`: where to choose a paid plan.'
            alternative:
              type: string
              description: 'On `real_face_needs_paid`: the field that works on every plan instead (`person.describe`).'
            person_url:
              type: string
              description: 'On a recast with `person.describe` whose recast step was refused after the person was made: the AI person, in your Library. Send it as `person.image_url` to retry without making a new one.'
        request_id:
          type: string
          nullable: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: hmk_...
      description: A Hermoso API key, or an access token from the OAuth authorization-code flow (which is the same thing).
x-refined-from:
- app_hermoso_ai.json
- app_hermoso_ai_rest.json