snaplab-dev Account API

API keys, plan and usage.

Operations 5

GET /api/keys List API keys #
POST /api/keys Create an API key #
DELETE /api/keys/{id} Revoke an API key #
GET /api/me The current account, plan and usage #
PATCH /api/me Set the account-default capture webhook #

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/snaplab-dev:snaplab-dev-account-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

snaplab-dev-account-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: snaplab Account API
  version: 1.0.0
  summary: Turn any URL or HTML into a screenshot, a PDF, or a social image.
  description: 'snaplab renders web pages with a real headless Chromium and hands you the bytes.


    - `POST|GET /api/render` — URL **or** raw HTML → PNG / JPEG / WebP / AVIF / PDF, viewport or full page, retina, dark mode, element clipping.

    - `POST|GET /api/render/image` — HTML (or a `{{ template }}` + `data`) → a fixed-size image. The Open Graph card path.

    - `POST /api/render/preview` — unauthenticated, rate-limited demo render.

    - `POST /api/tools/*` — key-less public tools, 20 renders/day/IP, always answered with a hosted URL.

    - `/mcp` — a stateless Streamable-HTTP MCP server exposing `screenshot`, `pdf`, `html_to_image` and `usage`.


    ## Authentication


    Every endpoint except `/api/health`, `/api/render/preview` and `/api/tools/*` needs an API key. Keys look like `sk_…`

    and are created in the dashboard or through `POST /api/keys`.


    1. `Authorization: Bearer sk_…` — the header form, accepted everywhere.

    2. Signed query parameters — `GET /api/render` and `GET /api/render/image` only. See below.

    3. The browser session cookie, for the dashboard itself.


    ### Signed URLs


    Putting a raw key in an `` leaks it. Sign the URL instead: append `keyId` (the API key''s id) and

    `sig=hex(HMAC_SHA256(signing_secret, canonical))`, optionally with an `expires` Unix timestamp. The canonical string is

    every query pair except `sig`, sorted by name then value and joined with `&`. The per-key signing secret and a URL

    builder live in the dashboard under Keys.


    ## Options


    Options are camelCase and identical between the JSON body and the query string. In a query string, booleans are

    `true`/`1` and `false`/`0`, `hideSelectors` is a comma-separated list, and PDF options take either the dotted form

    (`pdf.format=A4`) or the flat alias (`pdfFormat=A4`).


    ## Caching and quota


    Identical options are served from a shared cache for 24h. **Cache hits and failed renders do not count against your

    quota** — only fresh, successful renders do. Renders carry `X-Snaplab-Cache`, `X-Snaplab-Duration-Ms`,

    `X-Snaplab-Fingerprint` and `X-Snaplab-Quota-Remaining`.


    Pass `cache: false` to force a fresh render.


    ## Errors


    Errors are JSON: `{"error":"…","code":"…"}`. Messages are for humans; codes are stable.


    | Status | Code | Meaning |

    | --- | --- | --- |

    | 400 | — | A parameter is missing, malformed, out of range, or the target is a private/blocked address. |

    | 401 | `unauthorized` | Missing, unknown or revoked API key; or a bad signature. |

    | 402 | `payment_required` | The subscription is past due. |

    | 422 | `selector_not_found` | The page rendered but `selector` matched nothing. |

    | 429 | `quota_exceeded` | The monthly render allowance is used up. |

    | 429 | — | Too many requests per minute for your plan. |

    | 502 | `upstream` | The target site was unreachable. |

    | 503 | `capacity` / `not_ready` | The render queue is saturated, or the browsers are still starting. Retry shortly. |

    | 504 | `timeout` | The page did not finish in time. |


    ## Plans


    | Plan | Renders / month | Price | Rate | Concurrency |

    | --- | --- | --- | --- | --- |

    | free | 100 | $0 | 30/min | 1 |

    | starter | 2,000 | $9 | 120/min | 3 |

    | pro | 10,000 | $29 | 300/min | 5 |

    | business | 40,000 | $79 | 600/min | 10 |'
  termsOfService: https://snaplab.dev/terms
  contact:
    name: snaplab support
    url: https://snaplab.dev/docs
    email: snaplab.dev
  license:
    name: MIT
    identifier: MIT
servers:
- url: https://snaplab.dev
  description: Production
security:
- bearerAuth: []
tags:
- name: Account
  description: API keys, plan and usage.
paths:
  /api/keys:
    get:
      tags:
      - Account
      operationId: listKeys
      summary: List API keys
      description: Session-authenticated only — an API key cannot manage other keys. Also returns the account's signing secret for building signed URLs.
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Active keys.
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ApiKey'
                  signingSecret:
                    type: string
                    description: HMAC secret for signed URLs.
        '401':
          description: Not authenticated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: API keys can't manage other API keys.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      tags:
      - Account
      operationId: createKey
      summary: Create an API key
      description: The full `sk_…` token is returned exactly once — store it now.
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 80
              additionalProperties: false
            example:
              name: production
      responses:
        '200':
          description: The new key, with its plaintext token.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/ApiKey'
                - type: object
                  properties:
                    token:
                      type: string
                      example: sk_…
        '400':
          description: Invalid name.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not authenticated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: API keys can't create other API keys.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/keys/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
    delete:
      tags:
      - Account
      operationId: revokeKey
      summary: Revoke an API key
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Revoked.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
        '401':
          description: Not authenticated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: API keys can't manage other API keys.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /api/me:
    get:
      tags:
      - Account
      operationId: me
      summary: The current account, plan and usage
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Account, plan and month-to-date usage.
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  email:
                    type: string
                    format: email
                  name:
                    type: string
                  image:
                    type:
                    - string
                    - 'null'
                  createdAt:
                    type: string
                    format: date-time
                  authMethod:
                    type: string
                    enum:
                    - session
                    - apikey
                    - signature
                  plan:
                    type: string
                    enum:
                    - free
                    - starter
                    - pro
                    - business
                  planStatus:
                    type: string
                    example: active
                  usage:
                    type: object
                    properties:
                      used:
                        type: integer
                      limit:
                        type: integer
                      resetsAt:
                        type: string
                        format: date-time
                  billingConfigured:
                    type: boolean
                    description: False when Stripe isn't configured on this deployment.
                  webhookUrl:
                    type:
                    - string
                    - 'null'
                    format: uri
                    description: Account-default capture callback, used when a request names none.
                  webhookSecret:
                    type:
                    - string
                    - 'null'
                    description: Masked to the last four characters (`****1234`). The real secret is never returned.
        '401':
          description: Not authenticated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      tags:
      - Account
      operationId: updateMe
      summary: Set the account-default capture webhook
      description: Either field may be sent on its own; `null` or `""` clears it. Used by any capture that does not carry its own `webhookUrl`.
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                webhookUrl:
                  type:
                  - string
                  - 'null'
                  format: uri
                  maxLength: 2048
                  description: '`https://` only; private, loopback and metadata addresses are refused.'
                webhookSecret:
                  type:
                  - string
                  - 'null'
                  maxLength: 256
                  description: Signs every callback that uses this URL.
      responses:
        '200':
          description: The stored values, secret masked.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  webhookUrl:
                    type:
                    - string
                    - 'null'
                  webhookSecret:
                    type:
                    - string
                    - 'null'
                    description: Masked to the last four characters.
        '400':
          description: Nothing to update, or a webhook field that failed validation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not authenticated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: string
          description: Human-readable message.
        code:
          type: string
          description: Stable machine code, when one applies.
        retryable:
          type: boolean
        issues:
          type: array
          items:
            type: object
            additionalProperties: true
          description: Zod validation issues, for 400s.
        upgradeUrl:
          type: string
    ApiKey:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        prefix:
          type: string
          example: sk_abc123
        createdAt:
          type: string
          format: date-time
        lastUsedAt:
          type:
          - string
          - 'null'
          format: date-time
        revokedAt:
          type:
          - string
          - 'null'
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_<40 chars>
      description: 'Send the key as `Authorization: Bearer sk_…`. This is also how the MCP server at `/mcp` authenticates.'
    signedKeyId:
      type: apiKey
      in: query
      name: keyId
      description: 'Signed-URL auth (GET renders only): the API key''s **id**, not its secret. Pair with `sig`.'
    signedSignature:
      type: apiKey
      in: query
      name: sig
      description: '`hex(HMAC_SHA256(signingSecret, canonical))`, where canonical is every query pair except `sig`, sorted by name then value and joined with `&`. Add `expires` (Unix seconds) to time-limit the URL.'
externalDocs:
  description: snaplab documentation
  url: https://snaplab.dev/docs