SpicyAPI Models API

The Models API from SpicyAPI — 3 operation(s) for models.

Operations 3

GET /api/v1/models List callable models and account-specific prices #
GET /api/v1/models/{model} Get one model, including its input JSON Schema #
GET /console/v1/catalog/models Anonymous evaluation catalogue (no API key) #

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/spicyapi:spicyapi-models-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

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

spicyapi-models-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Spicyapi Models API
  version: 1.0.0
  description: 'Operations tagged Models across 2 of this provider''s published API definitions: spicyapi-openapi.yaml, spicyapi-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.spicyapi.ai
  description: Production
security:
- bearerAuth: []
tags:
- name: Models
paths:
  /api/v1/models:
    get:
      tags:
      - Models
      operationId: listModels
      summary: List callable models and account-specific prices
      description: 'Returns all enabled models without pagination. The response is private

        because prices include the authenticated account''s group multiplier.

        The server sends `Cache-Control: private, max-age=60`.'
      parameters:
      - name: modality
        in: query
        schema:
          type: string
          enum:
          - image
          - video
          - audio
          - text
      - name: provider
        in: query
        schema:
          type: string
        description: Exact model creator/author identifier, such as the research lab that built the model.
      - name: task
        in: query
        schema:
          type: string
        description: 'Exact supported task, for example `text-to-image`. Image editing accepts either spelling: `edit` (the published call suffix) and `image-to-image` (the value returned in `tasks`) select the same endpoints.'
      - name: search
        in: query
        schema:
          type: string
          maxLength: 128
      - name: includeSchema
        in: query
        schema:
          oneOf:
          - type: boolean
          - type: integer
            enum:
            - 0
            - 1
        description: Include each model's input JSON Schema when `true` or `1`.
      - name: includeExamples
        in: query
        schema:
          oneOf:
          - type: boolean
          - type: integer
            enum:
            - 0
            - 1
        description: Include validated example inputs when `true` or `1`.
      responses:
        '200':
          description: Model list.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, max-age=60
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelListEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
    servers:
    - url: https://api.spicyapi.ai
      description: Production
  /api/v1/models/{model}:
    get:
      tags:
      - Models
      operationId: getModel
      summary: Get one model, including its input JSON Schema
      description: '`model` is the exact value used by `createTask.model` and may contain

        slashes. URL-encode embedded slashes when using clients that treat path

        parameters as one segment (for example `family%2Fversion%2Ftask`).'
      parameters:
      - name: model
        in: path
        required: true
        allowReserved: true
        schema:
          type: string
          minLength: 1
      responses:
        '200':
          description: Complete model record.
          headers:
            Cache-Control:
              schema:
                type: string
                const: private, max-age=60
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ModelEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
    servers:
    - url: https://api.spicyapi.ai
      description: Production
  /console/v1/catalog/models:
    get:
      tags:
      - Models
      operationId: listPublicCatalog
      summary: Anonymous evaluation catalogue (no API key)
      security: []
      description: 'The one integration-relevant path that reads without credentials. It

        exists so that "which models are there and what do they cost" can be

        answered before signing up, which is the order integrations actually

        evaluate in.


        Use it while evaluating; use `GET /api/v1/models` once you hold a key.

        The authenticated catalogue is still the only source for callable model

        IDs at integration time: it is scoped to the key, carries the account''s

        group multiplier, the full input JSON Schema and validated examples,

        and it is the surface `createTask.model` is contractually tied to.

        This one is public, cached at the edge and priced at the standard rate.


        Each item carries both `model` and `slug` with the same value, so

        parsing code written here keeps working against `/api/v1/models`.


        The complete item shape (marketing copy, assets, family routing) is

        documented in `console-openapi.yaml`; the fields below are the ones an

        integration cares about, and the object carries more.'
      parameters:
      - name: locale
        in: query
        schema:
          type: string
          enum:
          - en
          - ja
          - ko
          - de
          - fr
          - es
          - pt-BR
          - ru
          - it
          - pl
          default: en
        description: Content language. Defaults to `en` when omitted. An unsupported value is rejected with 400 rather than silently falling back.
      - name: strict
        in: query
        schema:
          oneOf:
          - type: boolean
          - type: integer
            enum:
            - 0
            - 1
        description: When `1` or `true`, return only models whose copy is published in that exact locale, with no fallback. Sitemap generation needs this; integrations normally do not.
      responses:
        '200':
          description: Published catalogue for one locale.
          headers:
            Cache-Control:
              schema:
                type: string
                const: public, max-age=60, s-maxage=300, stale-while-revalidate=86400
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicCatalogEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
    servers:
    - url: https://api.spicyapi.ai
      description: Production
components:
  schemas:
    APIModelList:
      type: object
      required:
      - total
      - items
      properties:
        total:
          type: integer
          minimum: 0
        items:
          type: array
          items:
            $ref: '#/components/schemas/APIModel'
    ModelEnvelope:
      allOf:
      - $ref: '#/components/schemas/EnvelopeBase'
      - type: object
        required:
        - data
        properties:
          code:
            type: integer
            const: 200
          msg:
            type: string
            const: success
          data:
            $ref: '#/components/schemas/APIModel'
    USDString:
      type: string
      pattern: ^-?[0-9]+(?:\.[0-9]+)?$
      description: Decimal USD amount encoded as a string to avoid binary floating-point loss.
    PublicCatalogEnvelope:
      allOf:
      - $ref: '#/components/schemas/EnvelopeBase'
      - type: object
        required:
        - data
        properties:
          code:
            type: integer
            const: 200
          msg:
            type: string
            const: success
          data:
            $ref: '#/components/schemas/PublicCatalogList'
    PublicCatalogItem:
      type: object
      description: Evaluation view of one endpoint. Additional presentation fields are returned and documented in console-openapi.yaml.
      required:
      - model
      - slug
      - family
      - displayName
      - provider
      - modality
      - tasks
      - status
      - callable
      properties:
        model:
          type: string
          description: Same value as `slug`, under the field name `/api/v1/models` uses. This is the value `createTask.model` takes.
        slug:
          type: string
        aliases:
          type: array
          items:
            type: string
          description: Previously published identifiers that still resolve to this endpoint.
        family:
          type: string
        familyPageSlug:
          type: string
        familyDisplayName:
          type: string
        displayName:
          type: string
        provider:
          type: string
          description: The model's creator, for example `ByteDance`. Never an execution channel.
        modality:
          type: string
          enum:
          - image
          - video
          - audio
          - text
        tasks:
          type: array
          items:
            type: string
          description: Same values and meaning as APIModel.tasks, including the `edit` / `image-to-image` split.
        mature:
          type: boolean
        policyTier:
          type: string
          enum:
          - unrestricted
          - borderline
          - softened
          - filtered
          - unspecified
          description: Same values and meaning as APIModel.policyTier. Treat the set as open.
        toolkit:
          type: string
          enum:
          - subject-swap
          - studio-tools
          description: Which toolkit family this model belongs to (subject-swap for identity swaps; studio-tools for single-purpose image and video tools such as background removal or upscaling). Informational classification for catalogue grouping only; it does not participate in routing
          pricing or authorization. Absent when the model is not part of a toolkit.: null
        async:
          type: boolean
        status:
          type: string
          enum:
          - published
          - live
          - paused
          description: Operator intent. `live` is the only status that can be callable.
        callable:
          type: boolean
          description: Whether a fully priced, routable execution path exists right now. A callable endpoint always has a price; an endpoint without a price is never callable.
        price:
          oneOf:
          - $ref: '#/components/schemas/PublicCatalogPrice'
          - type: 'null'
          description: Standard-rate starting price, or absent when the endpoint is not currently sellable. It is never reported as `0`.
    EnvelopeBase:
      type: object
      required:
      - code
      - msg
      - request_id
      properties:
        code:
          type: integer
        msg:
          type: string
        request_id:
          type: string
          description: Correlation identifier. Include it in support requests.
    ErrorEnvelope:
      allOf:
      - $ref: '#/components/schemas/EnvelopeBase'
      - type: object
        properties:
          code:
            type: integer
            enum:
            - 400
            - 40003
            - 40004
            - 401
            - 40201
            - 40202
            - 403
            - 40301
            - 40302
            - 40303
            - 40310
            - 404
            - 409
            - 40901
            - 413
            - 429
            - 500
            - 503
            - 50301
            - 50302
            description: 'Business code. `40003`: an uploaded file''s actual size, media type or signature does not match its upload ticket (file commit). `40004`: the request is valid but no deployment can serve this exact parameter combination; change the named parameter and retry. `503`: a dependency is temporarily unavailable (for example a list or usage query timed out, or inline image storage failed); honour `Retry-After` when present. `50301`: the model has no usable deployment or effective price right now. `50302`: a synchronous generation (streaming) failed upstream and the charge was refunded. Retry with a **new** `Idempotency-Key` — the original key replays the same failure, so a transport-level retry that keeps the key can never succeed. `40301`: this key is not allowed to call this model — check the key''s model restrictions in the Console. `40302`: the caller''s address is not in this key''s IP allow-list. `40303`: the request comes from a region this service is not offered in; the message deliberately does not state how that is determined, and neither does this description. `40310`: the account has not verified its email address yet, so it cannot run models. Open the verification link that was emailed at sign-up, or send a new one from the Console; the key starts working as soon as the address is verified, with no change on your side.'
          msg:
            type: string
            description: Human-readable explanation, English unless `Accept-Language` or the account's API error language selects another supported language. Never parse it; branch on `code`.
    PublicCatalogList:
      type: object
      required:
      - locale
      - items
      - total
      properties:
        locale:
          type: string
          description: The locale the copy was resolved to.
        total:
          type: integer
        items:
          type: array
          items:
            $ref: '#/components/schemas/PublicCatalogItem'
    APIModel:
      type: object
      required:
      - model
      - family
      - displayName
      - provider
      - modality
      - tasks
      - async
      - mature
      - policyTier
      - taskTimeoutSeconds
      - enabled
      - available
      - quantityField
      - pricing
      - version
      - availability
      - badges
      - relatedModels
      - updatedAt
      properties:
        model:
          type: string
          description: Preferred callable identifier in publisher/model/task form. Image editing uses the edit suffix; previously published identifiers remain accepted.
          example: bytedance/seedream-5.0-lite/edit
        family:
          type: string
          description: Stable product-family identifier; endpoint variants are listed in `tasks` and expressed by `inputSchema`.
        displayName:
          type: string
        provider:
          type: string
          description: Model creator/author identifier, such as the research lab that built the model.
        modality:
          type: string
          enum:
          - image
          - video
          - audio
          - text
        tasks:
          type: array
          items:
            type: string
          description: 'The internal task classification of this one endpoint. Always exactly one element, and it is not always the suffix of `model`: image editing endpoints are published as `.../edit` but classified as `image-to-image`, because renaming the call did not reclassify the work. Use `model` to call, and `tasks[0]` only to group or filter. Other values match their suffix: `text-to-image`, `text-to-video`, `image-to-video`, `reference-to-video`, `video-edit`, `video-extend`, `video-analyze`, `character-animation`, `talking-avatar`, `lip-sync`, `video-to-audio` (returns the same video with a generated sound track), `frame-interpolation` (returns the same video at twice its frame rate, same length and audio), `layer-decomposition` (returns a base image plus transparent layers, see `TaskOutputAsset.layer`), `speech-to-text`, `chat`. New values appear as models are added, so treat the set as open.'
        async:
          type: boolean
        mature:
          type: boolean
          description: Informational model-creator capability metadata only. It does not participate in authorization, availability decisions, or request rejection.
        policyTier:
          type: string
          enum:
          - unrestricted
          - borderline
          - softened
          - filtered
          - unspecified
          description: 'Informational model-creator policy metadata only. It does not participate in authorization, availability decisions, or request rejection. `unrestricted`: the model adds no refusal layer of its own. `borderline`: its own policy lets some requests through and may still decline others. `softened`: it does not refuse and does not fail — it quietly returns a toned-down result, and that task settles and is charged like any other success. `filtered`: it declines requests its own policy restricts, which surfaces as a `content_rejected` failure. `unspecified`: no tier has been recorded for this model. Treat the set as open: a value you do not recognise must not break your client.'
        toolkit:
          type: string
          enum:
          - subject-swap
          - studio-tools
          description: Which toolkit family this model belongs to (subject-swap for identity swaps; studio-tools for single-purpose image and video tools such as background removal or upscaling). Informational classification for catalogue grouping only; it does not participate in routing, pricing or authorization. Absent when the model is not part of a toolkit.
        taskTimeoutSeconds:
          type: integer
          minimum: 1
          description: Absolute platform execution deadline before timeout/refund; not media output duration.
        maxOutputDurationSeconds:
          type: integer
          minimum: 1
          description: Maximum output duration the model schema allows, taken from the `maximum` of its `duration_seconds` property; omitted when that property is absent or has no declared maximum. Distinct from `taskTimeoutSeconds`, which is the platform execution deadline.
        enabled:
          type: boolean
        available:
          type: boolean
        quantityField:
          type: string
        pricing:
          type: array
          items:
            $ref: '#/components/schemas/APIModelPrice'
        startingPrice:
          $ref: '#/components/schemas/APIModelPrice'
        inputSchema:
          type: object
          description: 'JSON Schema draft 2020-12 used by `createTask.input` validation and Playground rendering. Standard JSON Schema keywords validate. Presentation hints live only in a per-property `x-ui` object whose keys are snake_case and drawn from a closed set: `widget`, `order`, `label`, `placeholder`, `rows`, `step`, `unit`, `accept`, `max_size_mb`, `advanced`, `primary`, `affects_price`, `visible_when`, `enum_labels`. `x-ui.order` is the only source of field order (descending first). `x-ui.widget` is one of `textarea`, `text`, `upload`, `multi-upload`, `select`, `radio`, `slider`, `number`, `switch`, `json`, `object-list`, `chat-messages`, `hidden`. Root-level composition is limited to `anyOf`, where every branch contains only `required`, and `allOf`, where each branch is `if` (`required` or `properties.*.const`) plus `then` (`required`); `oneOf`, `not` and `dependentSchemas` never appear. Unknown hints must be ignored.'
          additionalProperties: true
        version:
          type: string
          description: Public model-catalog version label used to detect schema or metadata changes.
        availability:
          type: string
          enum:
          - planned
          - available
          - preview
          - maintenance
        badges:
          type: array
          description: Closed capability and licensing vocabulary; clients should ignore unknown future IDs.
          items:
            type: string
            enum:
            - commercial_use
            - no_watermark
            - commercial_restricted
            - reference_input
            - audio_output
            - streaming
            - fast_tier
            - high_resolution
            - long_context
            - mature_capable
            - policy_unrestricted
            - policy_borderline
        relatedModels:
          type: array
          description: Curated model identifiers suitable for alternatives or workflow steps.
          items:
            type: string
        examples:
          type: array
          description: Inputs validated against this model's current input schema.
          items:
            $ref: '#/components/schemas/APIModelExample'
        updatedAt:
          type: string
          format: date-time
    APIModelExample:
      type: object
      required:
      - id
      - input
      - sortWeight
      properties:
        id:
          type: string
        input:
          type: object
          additionalProperties: true
        sortWeight:
          type: integer
    PublicCatalogPrice:
      type: object
      required:
      - amount
      - unit
      - tiers
      properties:
        amount:
          type: string
          description: Lowest tier's unit price as a decimal string. Decimal strings, not numbers, because these values are displayed and binary floats cannot represent them exactly.
        unit:
          type: string
          description: Billing unit identifier, for example per_image or per_second.
        variant:
          type: string
          description: The tier this price belongs to; absent when the model has one tier.
        tiers:
          type: integer
          description: Number of currently effective tiers. Greater than one means this is a starting price.
        regularAmount:
          type: string
          description: Pre-discount price
          present only when a customer offer applies.: null
        offerLabel:
          type: string
        offerPercent:
          type: string
        offerEndsAt:
          type: string
          format: date-time
        perMillionTokens:
          type: object
          description: Standard per-million-token prices for text models.
          required:
          - input
          - output
          properties:
            input:
              type: string
            cachedInput:
              type: string
            output:
              type: string
            cacheWrite:
              type: string
        listPrice:
          type: object
          description: The model creator's own published price, present only when ours is at least 1% lower. It is not our pre-discount price.
        variants:
          type: array
          description: 'Every priced tier of a per-second, per-image or per-request model, cheapest first (the first entry is the starting price). Absent for per-token models. `variant` is the raw tier key: a single value such as `720p`, or a compound key such as `generate_audio=false;resolution=1080p`.'
          items:
            type: object
            required:
            - variant
            - amount
            - unit
            properties:
              variant:
                type: string
              amount:
                type: string
              regularAmount:
                type: string
              unit:
                type: string
              listPrice:
                type: object
                description: This tier's own reference price, under the same rules as listPrice above.
    APIModelPrice:
      type: object
      required:
      - variant
      - unit
      - price
      - currency
      properties:
        variant:
          type: string
          description: Price tier key. Empty when the model has a single price. When one input field sets the price, it is that field's value as is (for example `720p`). When several fields do, it is `field=value` pairs sorted by field name and joined with `;` (for example `duration=5;resolution=720p`), with values URL-encoded; `~` stands for an optional field that was not sent and has no default.
        unit:
          type: string
          enum:
          - per_image
          - per_second
          - per_request
          - per_1k_tokens
          - per_1k_characters
        price:
          $ref: '#/components/schemas/USDString'
        regularPrice:
          $ref: '#/components/schemas/USDString'
        offerLabel:
          type: string
        offerPercent:
          type: string
        offerEndsAt:
          type: string
          format: date-time
        currency:
          type: string
          const: USD
        officialFallbackPrice:
          allOf:
          - $ref: '#/components/schemas/USDString'
          description: 'Present only for models with an economy route. `price` is then the economy-route price and this is the same tier''s official price: the most a request is charged when `official_fallback` is `true` and the economy route fails.'
    ModelListEnvelope:
      allOf:
      - $ref: '#/components/schemas/EnvelopeBase'
      - type: object
        required:
        - data
        properties:
          code:
            type: integer
            const: 200
          msg:
            type: string
            const: success
          data:
            $ref: '#/components/schemas/APIModelList'
  headers:
    RateLimitRemaining:
      description: Remaining requests in the active window.
      schema:
        type: integer
    RateLimitLimit:
      description: Capacity of the active account-level rate-limit window.
      schema:
        type: integer
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
        minimum: 1
  responses:
    Unauthorized:
      description: Missing, malformed, expired, revoked, or otherwise invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    BadRequest:
      description: Invalid JSON, query, callback URL, model input, or media declaration. Invalid callBackUrl values return code 400 and msg "Invalid callback URL" with request_id. Submitted hosts, IP addresses, and DNS diagnostics are not echoed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RateLimited:
      description: Account-level request limit exceeded.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    ServerError:
      description: Internal failure. Details are not exposed; report `request_id` to support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Forbidden:
      description: Account, model, API-key, IP, or region authorization failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    NotFound:
      description: Resource does not exist or is not visible to this account and API key. These cases are intentionally indistinguishable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk-spicy-<48 lowercase hex characters>
      description: 'Send `Authorization: Bearer sk-spicy-...`. Keep keys server-side.'
x-refined-from:
- spicyapi-openapi.yaml
- spicyapi-openapi.yml