Hermoso AI Signup API

The signup API from Hermoso AI — 2 operation(s) for signup.

GitHub OpenAPI

Operations 2

POST /v1/signup Start an agentic signup #
POST /v1/signup/{id}/claim Claim a paid signup (poll until ready) #

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-signup-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-signup-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hermoso Ai Signup API
  version: '2026-08-26'
  description: 'Operations tagged signup 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: Signup
paths:
  /v1/signup:
    post:
      operationId: createSignup
      summary: Start an agentic signup
      description: 'Create a Hermoso account programmatically, with no human at a browser and no existing credential — the one call in this API that needs no key, because the key is what it creates. Returns a Stripe Checkout URL and a one-time `claim_token`.


        AGENTIC SIGNUP REQUIRES A PAID PLAN. Nothing is created here: no account, no credits, no row. An account exists only once Stripe reports the payment completed, at which point `POST /v1/signup/{id}/claim` provisions it and returns your API key. The free plan is not available on this path — it is available to a person signing up at https://app.hermoso.ai.


        A card is entered on Stripe’s own hosted page, never here, so the checkout step itself needs a browser: hand `checkout_url` to whoever is paying. `claim_token` is returned exactly once and is the only proof this signup is yours — a checkout session id alone is not enough, because session ids travel in URLs.'
      tags:
      - Signup
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupCreate'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Signup'
        '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'
        '429':
          description: Rate limited. `Retry-After` says how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security: []
    servers:
    - url: https://app.hermoso.ai
  /v1/signup/{id}/claim:
    post:
      operationId: claimSignup
      summary: Claim a paid signup (poll until ready)
      description: 'Poll this until `status` is `ready`. While payment is outstanding it answers `awaiting_payment` and creates nothing. Once Stripe reports the payment completed it provisions the account, applies the plan and its credits, and returns `api_key` — ONCE.


        The key is stored only as a hash and can never be re-read. If you lose the response, re-claiming inside 24 hours mints a replacement and revokes the previous key, so a signup never leaves two live credentials behind. After that window there is no self-serve recovery: an agentic account has a synthetic identity and no mailbox to send a link to. Billing is always recoverable regardless — the payer receives Stripe’s receipts and can manage or cancel the subscription from Stripe’s own portal.'
      tags:
      - Signup
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
        description: The `id` from POST /v1/signup (a Stripe Checkout session id).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupClaim'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Signup'
        '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'
        '429':
          description: Rate limited. `Retry-After` says how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security: []
    servers:
    - url: https://app.hermoso.ai
components:
  schemas:
    Signup:
      type: object
      properties:
        object:
          type: string
          enum:
          - signup
        id:
          type: string
          description: Pass this to POST /v1/signup/{id}/claim.
        status:
          type: string
          enum:
          - awaiting_payment
          - ready
          description: This enum MAY GROW — tolerate a member you have not seen.
        plan:
          type: string
        period:
          type: string
          enum:
          - mo
          - yr
        checkout_url:
          type: string
          nullable: true
          description: Stripe’s hosted checkout. Present while payment is outstanding. A card is entered there, never here.
        expires_at:
          type: string
          nullable: true
          description: ISO-8601. When the checkout link stops working. Nothing is created and nothing is charged if it lapses.
        claim_token:
          type: string
          nullable: true
          description: Returned ONCE, by the create call. Store it before doing anything else — it is the only proof this signup is yours.
        api_key:
          type: string
          nullable: true
          description: Returned ONCE, on the claim that provisions the account (or on a re-claim inside 24h, which revokes the previous key). Stored only as a hash — it can never be re-read.
        account_id:
          type: string
          nullable: true
        credits:
          type: number
          nullable: true
          description: The plan’s credits, already granted.
        email:
          $ref: '#/components/schemas/ContactEmail'
          description: The contact mailbox and its verification state. Present from the create call on.
        next:
          type: string
          description: What to do now, in one sentence.
    SignupClaim:
      type: object
      required:
      - claim_token
      properties:
        claim_token:
          type: string
          description: The token returned exactly once by POST /v1/signup.
    SignupCreate:
      type: object
      required:
      - plan
      - email
      properties:
        plan:
          type: string
          description: 'A PAID plan id — see GET /v1/signup/plans-equivalent on hermoso.ai/pricing, currently starter, pro or studio. The free plan is refused here by name: this path provisions an account only against a completed payment.'
        period:
          type: string
          enum:
          - mo
          - yr
          description: Billing cadence. Defaults to `mo`.
        email:
          type: string
          description: 'REQUIRED: a real mailbox for the human this account belongs to. A verification link is emailed there; the account works before it is clicked, and verifying only decides whether we may mail the address (receipts, low-credit alerts, replies to bug reports). It is NEVER the account identity: it cannot sign in to this account, and it can never link or merge this account with one that already uses the address. Hermoso synthetic addresses are refused (400 `email_invalid`).'
    ContactEmail:
      type: object
      properties:
        address:
          type: string
          nullable: true
        verified:
          type: boolean
        verified_at:
          type: string
          nullable: true
          description: ISO-8601, or null while unverified.
        note:
          type: string
          description: What the state means, in one sentence.
    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