{
  "openapi": "3.1.0",
  "info": {
    "title": "1Capture Site API",
    "version": "2026-08-21",
    "summary": "Read 1Capture pricing and published content as JSON, and subscribe to the newsletter.",
    "description": "The public API of the 1Capture website. It exists so agents and\nintegrations can read what the site publishes without scraping HTML.\n\n**Permissions.** Every operation declares the scopes it needs. The read\nscopes (content:read, pricing:read) are granted to anonymous callers,\nbecause everything behind them is already published on the website.\nWrite scopes require an OAuth 2.0 client-credentials token, and a client\ncan only be issued the scopes it is registered for, so an agent holds\nexactly the access it needs.\n\n**Errors.** Every failure returns the same JSON envelope: a stable\n`error.code`, a human-readable `error.message`, an `error.resolution`\ntelling you what to do next, and an `error.request_id` to quote in a\nbug report. No endpoint under /api ever returns an HTML error page.\n\n**Credentials.** API clients are provisioned on request. Email\ncontact@1capture.io or join the developer waitlist at /docs/api.\n\nThe 1Capture platform API (trials, payments, webhooks) is a separate\nsurface in private preview and is not described here.",
    "termsOfService": "https://www.1capture.io/terms",
    "contact": {
      "name": "1Capture support",
      "email": "contact@1capture.io",
      "url": "https://www.1capture.io/contact"
    }
  },
  "servers": [
    {
      "url": "https://www.1capture.io",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "1Capture developer documentation",
    "url": "https://www.1capture.io/docs/api"
  },
  "tags": [
    {
      "name": "Discovery",
      "description": "Machine-readable descriptions of this site."
    },
    {
      "name": "Pricing",
      "description": "The published pricing model."
    },
    {
      "name": "Content",
      "description": "Published blog and comparison articles."
    },
    {
      "name": "Newsletter",
      "description": "Newsletter subscriptions."
    },
    {
      "name": "Authorization",
      "description": "OAuth 2.0 tokens and scopes."
    }
  ],
  "security": [
    {}
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getOpenApiDocument",
        "summary": "This OpenAPI document",
        "description": "Returns the OpenAPI 3.1 description of the Site API.",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "The OpenAPI document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getLlmsTxt",
        "summary": "Site guide for language models",
        "description": "An llms.txt guide to the site: what 1Capture is, and where the important pages live.",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "Markdown guide, served as text/plain.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "operationId": "getApiIndex",
        "summary": "API index",
        "description": "Lists every endpoint in this API, the scopes each one needs, and where the machine-readable descriptions live.",
        "security": [
          {}
        ],
        "responses": {
          "200": {
            "description": "The API index.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/pricing": {
      "get": {
        "tags": [
          "Pricing"
        ],
        "operationId": "getPricing",
        "summary": "Published pricing tiers",
        "description": "The full pricing model: every tier, its monthly fee, and the MRR band it applies to. This is the same data the /pricing page renders.",
        "security": [
          {},
          {
            "OAuth2ClientCredentials": [
              "pricing:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "The pricing model.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pricing"
                }
              }
            }
          },
          "403": {
            "description": "The token is missing the pricing:read scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/content/posts": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "listPosts",
        "summary": "List published articles",
        "description": "Every published blog post and competitor comparison, newest first.",
        "security": [
          {},
          {
            "OAuth2ClientCredentials": [
              "content:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by article type.",
            "schema": {
              "type": "string",
              "enum": [
                "blog",
                "comparison"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of articles to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of articles to skip.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of article summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostList"
                }
              }
            }
          },
          "400": {
            "description": "A query parameter is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The token is missing the content:read scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/content/posts/{slug}": {
      "get": {
        "tags": [
          "Content"
        ],
        "operationId": "getPost",
        "summary": "Read one article",
        "description": "One published article, including its metadata and canonical URL.",
        "security": [
          {},
          {
            "OAuth2ClientCredentials": [
              "content:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "The article slug, as it appears in its URL.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Which collection to look in. Both are searched when omitted.",
            "schema": {
              "type": "string",
              "enum": [
                "blog",
                "comparison"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The article.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Post"
                }
              }
            }
          },
          "403": {
            "description": "The token is missing the content:read scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No article matches that slug.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/newsletter/subscriptions": {
      "post": {
        "tags": [
          "Newsletter"
        ],
        "operationId": "createNewsletterSubscription",
        "summary": "Subscribe an address to the newsletter",
        "description": "Adds an email address to the 1Capture newsletter list. Requires the newsletter:write scope, so an agent must hold a token that was issued for it.",
        "security": [
          {
            "OAuth2ClientCredentials": [
              "newsletter:write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscribeRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The address is subscribed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "400": {
            "description": "The body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "No access token was supplied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The token is missing the newsletter:write scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The email address failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "The newsletter provider rejected the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Newsletter delivery is not configured.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/oauth/token": {
      "post": {
        "tags": [
          "Authorization"
        ],
        "operationId": "createAccessToken",
        "summary": "Exchange client credentials for a scoped access token",
        "description": "OAuth 2.0 client credentials grant (RFC 6749 section 4.4).\n\nSend `grant_type=client_credentials` as form data, authenticate with\nHTTP Basic or with `client_id`/`client_secret` fields, and ask for the\nnarrowest `scope` your agent needs. Omitting `scope` grants every scope\nthe client is registered for.",
        "security": [
          {
            "BasicAuth": []
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "An OAuth 2.0 error (invalid_request, invalid_scope, unsupported_grant_type).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "401": {
            "description": "Client authentication failed (invalid_client).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Token issuing is not configured on this deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "OAuth2ClientCredentials": {
        "type": "oauth2",
        "description": "Machine-to-machine tokens. Ask for the narrowest scope your agent needs; a client is only ever issued scopes it is registered for.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://www.1capture.io/api/v1/oauth/token",
            "refreshUrl": "https://www.1capture.io/api/v1/oauth/token",
            "scopes": {
              "content:read": "Read published site content: blog posts, comparison pages, and their metadata.",
              "pricing:read": "Read the published pricing tiers, the free threshold, and plan rules.",
              "newsletter:write": "Subscribe an email address to the 1Capture newsletter list."
            }
          }
        }
      },
      "BasicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "Client authentication at the token endpoint only (RFC 6749 section 2.3.1). Never used on resource endpoints."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "The error envelope returned by every endpoint under /api.",
        "required": [
          "error",
          "status"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "resolution",
              "documentation_url",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable code.",
                "examples": [
                  "insufficient_scope",
                  "not_found",
                  "validation_failed"
                ]
              },
              "message": {
                "type": "string",
                "description": "What went wrong, in one sentence."
              },
              "resolution": {
                "type": "string",
                "description": "What to do next to make the request succeed."
              },
              "documentation_url": {
                "type": "string",
                "format": "uri"
              },
              "request_id": {
                "type": "string",
                "description": "Quote this when reporting a problem."
              },
              "details": {
                "description": "Field-level or upstream detail, when there is any."
              }
            }
          },
          "status": {
            "type": "integer",
            "description": "Mirrors the HTTP status code."
          }
        }
      },
      "OAuthError": {
        "type": "object",
        "description": "An OAuth 2.0 error response (RFC 6749 section 5.2).",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "invalid_request",
              "invalid_client",
              "invalid_scope",
              "unsupported_grant_type"
            ]
          },
          "error_description": {
            "type": "string"
          },
          "error_uri": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "TokenRequest": {
        "type": "object",
        "required": [
          "grant_type"
        ],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": [
              "client_credentials"
            ]
          },
          "client_id": {
            "type": "string",
            "description": "Required unless you authenticate with HTTP Basic."
          },
          "client_secret": {
            "type": "string",
            "description": "Required unless you authenticate with HTTP Basic."
          },
          "scope": {
            "type": "string",
            "description": "Space-delimited scopes. One or more of: content:read, pricing:read, newsletter:write."
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "scope"
        ],
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "Bearer"
            ]
          },
          "expires_in": {
            "type": "integer",
            "description": "Token lifetime in seconds."
          },
          "scope": {
            "type": "string",
            "description": "The scopes actually granted, space-delimited."
          }
        }
      },
      "PricingTier": {
        "type": "object",
        "required": [
          "id",
          "name",
          "price_label",
          "monthly_fee_usd",
          "mrr_range",
          "min_mrr_usd",
          "description"
        ],
        "properties": {
          "id": {
            "type": "string",
            "examples": [
              "free",
              "growth"
            ]
          },
          "name": {
            "type": "string"
          },
          "price_label": {
            "type": "string",
            "examples": [
              "$95/mo"
            ]
          },
          "monthly_fee_usd": {
            "type": "number"
          },
          "mrr_range": {
            "type": "string",
            "examples": [
              "$10K to $50K MRR"
            ]
          },
          "min_mrr_usd": {
            "type": "number"
          },
          "max_mrr_usd": {
            "type": [
              "number",
              "null"
            ],
            "description": "Exclusive upper bound. null on the top tier."
          },
          "description": {
            "type": "string"
          }
        }
      },
      "Pricing": {
        "type": "object",
        "required": [
          "object",
          "currency",
          "tiers"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "pricing"
          },
          "currency": {
            "type": "string",
            "examples": [
              "usd"
            ]
          },
          "summary": {
            "type": "string"
          },
          "free_below_mrr_usd": {
            "type": "number"
          },
          "requires_credit_card": {
            "type": "boolean"
          },
          "transaction_fees": {
            "type": "boolean"
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PricingTier"
            }
          },
          "documentation_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "PostSummary": {
        "type": "object",
        "required": [
          "type",
          "slug",
          "title",
          "url",
          "date"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "blog",
              "comparison"
            ]
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "excerpt": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "date": {
            "type": "string"
          },
          "updated": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "reading_time": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "PostList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "total",
          "limit",
          "offset"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostSummary"
            }
          },
          "total": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          }
        }
      },
      "Post": {
        "allOf": [
          {
            "$ref": "#/components/schemas/PostSummary"
          },
          {
            "type": "object",
            "properties": {
              "keywords": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "headings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "text": {
                      "type": "string"
                    },
                    "level": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "SubscribeRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "company": {
            "type": "string",
            "maxLength": 255
          },
          "monthly_trials": {
            "type": "string",
            "maxLength": 255
          }
        }
      },
      "Subscription": {
        "type": "object",
        "required": [
          "object",
          "email",
          "status"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "newsletter_subscription"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "status": {
            "type": "string",
            "enum": [
              "subscribed"
            ]
          }
        }
      },
      "ApiIndex": {
        "type": "object",
        "required": [
          "object",
          "version",
          "endpoints",
          "scopes"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "api_index"
          },
          "version": {
            "type": "string"
          },
          "documentation_url": {
            "type": "string",
            "format": "uri"
          },
          "openapi_url": {
            "type": "string",
            "format": "uri"
          },
          "llms_txt_url": {
            "type": "string",
            "format": "uri"
          },
          "sitemap_url": {
            "type": "string",
            "format": "uri"
          },
          "token_endpoint": {
            "type": "string",
            "format": "uri"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "name",
                "description",
                "anonymous"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "anonymous": {
                  "type": "boolean",
                  "description": "True when callers hold this scope without a token."
                }
              }
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "method",
                "path",
                "summary",
                "scopes"
              ],
              "properties": {
                "method": {
                  "type": "string"
                },
                "path": {
                  "type": "string"
                },
                "summary": {
                  "type": "string"
                },
                "scopes": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}