ClearList Account API

Tier, capacity, and payment links.

Operations 4

GET /api/pages/renewal-options Get sale-page renewal choices #
POST /api/pages/extend Renew or begin renewing a sale page #
GET /api/payments/status Check tier, capacity, and expiry #

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/clearlist-me:clearlist-me-account-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

clearlist-me-account-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ClearList Account API
  version: 0.3.6
  description: 'API for ClearList, an AI resale manager. Agents authenticate via an API key acquired through the email verification flow, or as an OAuth 2.1 client (see /auth.md). Standard response envelope: `{ success: boolean, data?: object, error?: string }`. Errors return the Error schema with a machine-readable `code` and a resolution `hint`. Versioning: every response carries an X-API-Version header (currently 0.3); breaking changes ship as a new version and the old behavior is kept through a deprecation window announced via Deprecation and Sunset headers (RFC 8594) and the changelog at /developers. Retries: the operations that declare the Idempotency-Key header parameter accept it (1-255 chars; a UUID works well). The first successful (2xx) response is stored for 24h, and a retry with the same key replays it instead of duplicating the side effect, marked by an Idempotency-Replayed: true response header. An error returned by the operation itself is never stored and releases the key, so retrying that same request re-executes it. A key is scoped to the seller and the operation, and it identifies ONE request: while its record is live (the first request is still running, or it succeeded within the last 24h), the same key on the same operation with a different request body (compared byte for byte, so reformatted JSON counts as different) or from a different kind of credential (a signed-in session, an API key, and an OAuth token are three kinds) is refused with 422 `idempotency_key_reuse`. That refusal leaves the original record in place, so a corrected request needs a NEW key. A key outside the allowed characters is refused with 400 `invalid_idempotency_key`. Do not assume an operation is retry-safe because it looks like an update: check for the parameter on the operation itself.'
  contact:
    email: hello@clearlist.me
    url: https://clearlist.me
servers:
- url: https://clearlist.me
  description: Production
security:
- apiKey: []
- oauth2: []
tags:
- name: Account
  description: Tier, capacity, and payment links.
paths:
  /api/pages/renewal-options:
    get:
      operationId: getPageRenewalOptions
      tags:
      - Account
      summary: Get sale-page renewal choices
      description: Returns the authenticated seller's current page expiry and the renewal choices that can be fulfilled in full. Checkout URLs are omitted when the page is unpublished or no option is currently eligible.
      responses:
        '200':
          description: Current renewal state.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      can_renew:
                        type: boolean
                      is_free:
                        type: boolean
                      page_expires_at:
                        type: string
                        format: date-time
                        nullable: true
                      days_until_page_expiry:
                        type: integer
                        nullable: true
                      is_expired:
                        type: boolean
                      options:
                        type: array
                        items:
                          type: object
                          properties:
                            intent:
                              type: string
                              enum:
                              - free_renew
                              - time_only
                              - renew_pass
                              - upgrade
                            label:
                              type: string
                            detail:
                              type: string
                            priceUsd:
                              type: number
                            durationDays:
                              type: integer
                            addsCapacity:
                              type: boolean
                            sku:
                              type: string
                              enum:
                              - sale_pass
                              - big_move
                              - move_extension
                              - garage_extension
                            checkout_url:
                              type: string
                              format: uri
                              nullable: true
        '401':
          $ref: '#/components/responses/Unauthorized'
  /api/pages/extend:
    post:
      operationId: extendSalePage
      security:
      - apiKey: []
      - oauth2:
        - write
      x-tool-id: extend_sale_page
      tags:
      - Account
      summary: Renew or begin renewing a sale page
      description: Renews an eligible free page immediately. Paid or lapsed-paid accounts receive purchasable choices instead; this endpoint never grants paid time for free. Pass an Idempotency-Key when retrying.
      responses:
        '200':
          description: Page extended, or payment choices returned.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      extended:
                        type: boolean
                      requires_payment:
                        type: boolean
                      page_expires_at:
                        type: string
                        format: date-time
                        nullable: true
                      days_until_page_expiry:
                        type: integer
                        nullable: true
                      url:
                        type: string
                        format: uri
                      options:
                        type: array
                        items:
                          type: object
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: 'Page is unpublished, renewal is too early, or account state changed. Also returned with `code: idempotency_conflict` while a request with the same Idempotency-Key is still being processed; that one is worth retrying with the same key after a few seconds. A 409 without that code is the operation''s own refusal: read `error`.'
        '422':
          $ref: '#/components/responses/IdempotencyKeyReuse'
        '429':
          $ref: '#/components/responses/RateLimited'
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
  /api/payments/status:
    get:
      operationId: checkTierStatus
      x-tool-id: check_tier_status
      tags:
      - Account
      summary: Check tier, capacity, and expiry
      responses:
        '200':
          description: Tier status.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      tier:
                        type: string
                      items_remaining:
                        type: integer
                      expires_at:
                        type: string
                        nullable: true
                      page_expires_at:
                        type: string
                        format: date-time
                        nullable: true
                      days_until_page_expiry:
                        type: integer
                        nullable: true
                      can_renew:
                        type: boolean
                      renewal:
                        type: object
                        description: Current eligible renewal choices. Empty outside the renewal window or when no full-duration purchase can be delivered.
        '401':
          $ref: '#/components/responses/Unauthorized'
  /api/payments/checkout-link:
    post:
      operationId: generatePaymentLink
      security:
      - apiKey: []
      - oauth2:
        - write
      x-tool-id: generate_payment_link
      tags:
      - Account
      summary: Generate a checkout link
      description: 'Returns a Stripe checkout URL for the requested plan. Send the URL to the user to pay in a browser; poll /api/payments/status to confirm. Naturally idempotent: no record is created; retries return the same payment link.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - plan
              properties:
                plan:
                  type: string
                  enum:
                  - sale_pass
                  - big_move
                  - move_extension
                  - garage_extension
      responses:
        '200':
          description: 'Checkout link — or `already_paid`. When the account already holds an equal-or-higher active plan, the 200 carries `data.already_paid: true` with `plan`, `expires_at` and a human-readable `message` instead of a link; do NOT send the user to checkout in that case. Upgrades (sale_pass → big_move) still return a link.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      checkout_url:
                        type: string
                        format: uri
                        description: Stripe-hosted checkout URL. Absent when already_paid is true.
                      already_paid:
                        type: boolean
                        description: Present and true only when no link was issued because the current plan already covers the request.
                      plan:
                        type: string
                      plan_name:
                        type: string
                      items_limit:
                        type: number
                      duration_days:
                        type: number
                      expires_at:
                        type: string
                        format: date-time
                        description: Only on already_paid responses.
                      suggested_action:
                        type: string
                        description: Only on already_paid responses, when a time extension is available. Currently always "extend".
                      suggested_sku:
                        type: string
                        enum:
                        - move_extension
                        - garage_extension
                        description: Only on already_paid responses. Call this endpoint again with plan set to this value to get a checkout link for 30 more days at the same item limit.
                      suggested_price_usd:
                        type: number
                        description: Price of suggested_sku in USD.
                      message:
                        type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
      x-payment-info:
        intent: charge
        method: stripe
        amount: 20
        currency: USD
        description: 'One-time pass purchase via Stripe Checkout (no subscription). Amount depends on the plan in the request body: sale_pass = 20.00 USD, big_move = 39.00 USD. The response returns a Stripe-hosted checkout URL; a human completes payment in the browser and the account upgrades via webhook.'
components:
  headers:
    WWWAuthenticate:
      schema:
        type: string
      description: 'RFC 9728 challenge: `Bearer resource_metadata="https://clearlist.me/.well-known/oauth-protected-resource", error="invalid_token"`.'
    RateLimitRemaining:
      schema:
        type: integer
      description: Requests remaining in the current window.
    RateLimitLimit:
      schema:
        type: integer
      description: Request quota for the current window.
    RateLimitReset:
      schema:
        type: integer
      description: Unix epoch seconds when the window resets.
  responses:
    RateLimited:
      description: Too many requests.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    IdempotencyKeyReuse:
      description: '`code: idempotency_key_reuse`. While an earlier request with this Idempotency-Key is still running or succeeded within the last 24h, the key was sent to the same operation with a different body (compared byte for byte) or from a different kind of credential (signed-in session, API key, or OAuth token). Nothing was executed and the original record is untouched, so retrying with this key repeats the 422. Send the request with a new key.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid API key.
      headers:
        WWW-Authenticate:
          $ref: '#/components/headers/WWWAuthenticate'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BadRequest:
      description: Invalid or missing parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: 'Unique client-generated key (1-255 chars from A-Za-z0-9_-:.; a UUID works well), scoped to the seller and the operation. The first successful (2xx) response is stored for 24h; retrying the identical request with the same key replays it instead of re-executing, so network-failure retries never create duplicates. A duplicate that arrives while the first is still running gets 409 idempotency_conflict. The same key with a different body (byte for byte) or a different kind of credential gets 422 idempotency_key_reuse and leaves the original record in place: send a new key. An error the operation itself returns is never stored and releases the key.'
      schema:
        type: string
        minLength: 1
        maxLength: 255
        pattern: ^[A-Za-z0-9_:.-]+$
  schemas:
    Error:
      type: object
      required:
      - success
      - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          description: Human-readable error message.
        code:
          type: string
          description: Machine-readable error code, e.g. route_not_found, invalid_token, rate_limited.
        message:
          type: string
          description: Detailed message.
        hint:
          type: string
          description: Resolution guidance for agents.
        retryable:
          type: boolean
          description: Present on refusals that are worth retrying unchanged. Currently only a wrong-conversation address confirmation, where the token is untouched and only the id was wrong. Absent means terminal.
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-ClearList-API-Key
      description: 'API key in `cl_<64-hex>` format. Obtained via POST /api/auth/verify-code with `{ email, code, agent: true }`. Always full access (read and write). The same credential is also accepted as `Authorization: Bearer cl_<64-hex>`.'
    oauth2:
      type: oauth2
      description: 'OAuth 2.1 authorization code flow. PKCE with code_challenge_method=S256 is required; public clients only (token_endpoint_auth_method none). Access tokens are `cl_<64-hex>` and are sent as `Authorization: Bearer <token>` (X-ClearList-API-Key also works). Operations that change state require the `write` scope; a grant without it gets 403. Reading needs no specific scope, so a `write`-only grant can also read.'
      flows:
        authorizationCode:
          authorizationUrl: https://clearlist.me/oauth/authorize
          tokenUrl: https://clearlist.me/api/oauth/token
          refreshUrl: https://clearlist.me/api/oauth/token
          scopes:
            read: Read listings, reservations, conversations, page stats and plan status.
            write: Create, edit, delete and publish listings; reply to buyers; share an address through the confirmed flow; set availability; create payment links.
    bearerToken:
      type: http
      scheme: bearer
      description: 'Firebase ID token for web UI authentication. A `Bearer cl_…` value is not a Firebase token: it is an API key or OAuth access token, covered by the apiKey and oauth2 schemes.'