openapi: 3.0.3
info:
  title: Agent SP-API
  version: "2026-03-04"
  description: |
    Hypermedia-first API for accessing account context and queryable SQLite relations.
    Public endpoints are versioned under `/api/v1` and return `data` + `links` + `meta` envelopes.
servers:
  - url: https://www.agentspapi.com
tags:
  - name: Discovery
    description: API entrypoint and navigation links.
  - name: Identity
    description: Endpoints for verifying caller identity and API key context.
  - name: Querying
    description: Endpoints for listing and querying partner SQLite tables and views.
security:
  - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key Token
      description: |
        Use a key created in the API Keys dashboard.
        Token format: `rz_live_<key_id>_<secret>`
  schemas:
    Link:
      type: object
      properties:
        href:
          type: string
          format: uri
        method:
          type: string
          example: GET
        templated:
          type: boolean
        hints:
          type: object
          additionalProperties: true
      required: [href, method]
    Links:
      type: object
      additionalProperties:
        $ref: "#/components/schemas/Link"
    Meta:
      type: object
      properties:
        request_id:
          type: string
        contract_version:
          type: string
          example: "2026-03-04"
      required: [request_id, contract_version]
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
      required: [code, message]
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: "#/components/schemas/Error"
        links:
          $ref: "#/components/schemas/Links"
        meta:
          $ref: "#/components/schemas/Meta"
      required: [error, links, meta]
    EntrypointData:
      type: object
      properties:
        name:
          type: string
        version:
          type: string
      required: [name, version]
    EntrypointResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/EntrypointData"
        links:
          $ref: "#/components/schemas/Links"
        meta:
          $ref: "#/components/schemas/Meta"
      required: [data, links, meta]
    UserContext:
      type: object
      properties:
        id:
          type: integer
        email:
          type: string
          format: email
      required: [id, email]
    ApiKeyContext:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        key_id:
          type: string
        revoked_at:
          type: string
          nullable: true
          format: date-time
      required: [id, name, key_id, revoked_at]
    MeData:
      type: object
      properties:
        user:
          $ref: "#/components/schemas/UserContext"
        api_key:
          $ref: "#/components/schemas/ApiKeyContext"
      required: [user, api_key]
    MeResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/MeData"
        links:
          $ref: "#/components/schemas/Links"
        meta:
          $ref: "#/components/schemas/Meta"
      required: [data, links, meta]
    RelationResource:
      type: object
      properties:
        name:
          type: string
        relation_type:
          type: string
          enum: [table, view]
        links:
          $ref: "#/components/schemas/Links"
      required: [name, relation_type, links]
    TablesData:
      type: array
      items:
        $ref: "#/components/schemas/RelationResource"
    TablesMeta:
      allOf:
        - $ref: "#/components/schemas/Meta"
        - type: object
          properties:
            count:
              type: integer
          required: [count]
    TablesResponse:
      type: object
      properties:
        data:
          $ref: "#/components/schemas/TablesData"
        links:
          $ref: "#/components/schemas/Links"
        meta:
          $ref: "#/components/schemas/TablesMeta"
      required: [data, links, meta]
    QueryRow:
      type: object
      additionalProperties: true
    QueryMeta:
      allOf:
        - $ref: "#/components/schemas/Meta"
        - type: object
          properties:
            table_name:
              type: string
            limit:
              type: integer
            offset:
              type: integer
            returned_count:
              type: integer
            total_count:
              type: integer
              nullable: true
            applied_prefer:
              type: string
            content_range:
              type: string
          required: [table_name, limit, offset, returned_count]
    QueryResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/QueryRow"
        links:
          $ref: "#/components/schemas/Links"
        meta:
          $ref: "#/components/schemas/QueryMeta"
      required: [data, links, meta]
paths:
  /api/v1:
    get:
      operationId: getApiEntrypoint
      tags: [Discovery]
      summary: Get API entrypoint links
      description: |
        Returns top-level links that drive API navigation.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Entrypoint resource
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EntrypointResponse"
              examples:
                entrypoint:
                  summary: Entrypoint with discoverable links
                  value:
                    data:
                      name: Agent SP-API
                      version: v1
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1
                        method: GET
                      me:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                      tables:
                        href: https://www.agentspapi.com/api/v1/tables
                        method: GET
                      query_template:
                        href: https://www.agentspapi.com/api/v1/query/{table_name}{?select,order,limit,offset}
                        method: GET
                        templated: true
                    meta:
                      request_id: 2d172d8f-4c9a-4d7d-a6b3-65ff746f41be
                      contract_version: "2026-03-04"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                missingBearerToken:
                  summary: Missing bearer token
                  value:
                    error:
                      code: unauthorized
                      message: Missing bearer token
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1
                        method: GET
                    meta:
                      request_id: c62bb4b6-ef88-4f8d-a8ca-f8f7f6dcbf60
                      contract_version: "2026-03-04"
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
                minimum: 1
              example: 60
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /api/v1/me:
    get:
      operationId: getCurrentCaller
      tags: [Identity]
      summary: Verify API key and return caller context
      description: |
        Returns the authenticated user and API key context for the supplied Bearer token.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Authenticated caller information
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MeResponse"
              examples:
                validApiKey:
                  summary: Valid API key
                  value:
                    data:
                      user:
                        id: 42
                        email: developer@example.com
                      api_key:
                        id: 118
                        name: Production Agent
                        key_id: 1a2b3c4d5e6f
                        revoked_at: null
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                      entrypoint:
                        href: https://www.agentspapi.com/api/v1
                        method: GET
                      tables:
                        href: https://www.agentspapi.com/api/v1/tables
                        method: GET
                    meta:
                      request_id: 2d172d8f-4c9a-4d7d-a6b3-65ff746f41be
                      contract_version: "2026-03-04"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                missingBearerToken:
                  summary: Missing bearer token
                  value:
                    error:
                      code: unauthorized
                      message: Missing bearer token
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                    meta:
                      request_id: c62bb4b6-ef88-4f8d-a8ca-f8f7f6dcbf60
                      contract_version: "2026-03-04"
                invalidApiKey:
                  summary: Invalid API key
                  value:
                    error:
                      code: unauthorized
                      message: Invalid API key
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                    meta:
                      request_id: 33ed23ce-c507-4ef6-9ea8-64cce0ede204
                      contract_version: "2026-03-04"
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
                minimum: 1
              example: 60
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                rateLimitExceeded:
                  summary: Per-key API throttle exceeded
                  value:
                    error:
                      code: rate_limit_exceeded
                      message: Rate limit exceeded
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                    meta:
                      request_id: 1707d102-05e6-4bb9-a3f2-e17dbf81fa3a
                      contract_version: "2026-03-04"
  /api/v1/tables:
    get:
      operationId: listQueryableRelations
      tags: [Querying]
      summary: List queryable tables and views
      description: |
        Returns table and view names that are queryable for the API key's selling partner,
        including per-table query links.
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Queryable relation resources
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TablesResponse"
              examples:
                relationResources:
                  summary: Partner relation resources
                  value:
                    data:
                      - name: sales_traffic_sku_month_summaries
                        relation_type: table
                        links:
                          query:
                            href: https://www.agentspapi.com/api/v1/query/sales_traffic_sku_month_summaries
                            method: GET
                      - name: settlement_summaries
                        relation_type: view
                        links:
                          query:
                            href: https://www.agentspapi.com/api/v1/query/settlement_summaries
                            method: GET
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/tables
                        method: GET
                      entrypoint:
                        href: https://www.agentspapi.com/api/v1
                        method: GET
                      me:
                        href: https://www.agentspapi.com/api/v1/me
                        method: GET
                    meta:
                      request_id: 2d172d8f-4c9a-4d7d-a6b3-65ff746f41be
                      contract_version: "2026-03-04"
                      count: 2
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "409":
          description: Database snapshot is not ready yet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                databaseSyncing:
                  summary: Data sync in progress
                  value:
                    error:
                      code: database_syncing
                      message: We are syncing Amazon data to your secure database
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/tables
                        method: GET
                    meta:
                      request_id: d315cf8c-b378-4fdc-a0c1-06ebfa09e814
                      contract_version: "2026-03-04"
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
                minimum: 1
              example: 60
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
  /api/v1/query/{table_name}:
    get:
      operationId: queryRelationRows
      tags: [Querying]
      summary: Query a table or view
      description: |
        Runs a read-only query against a partner-scoped table or view.
        Filters are expressed as `<column>=<operator>.<value>`, for example `data_start_time=gt.2026-01-01`.
        Supported operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `is`, `like`.
      security:
        - bearerAuth: []
      parameters:
        - in: path
          name: table_name
          required: true
          schema:
            type: string
          description: Name of the table or view to query.
        - in: query
          name: select
          required: false
          schema:
            type: string
          description: Comma-separated list of columns to return.
        - in: query
          name: order
          required: false
          schema:
            type: string
          description: Comma-separated list of sort expressions like `price.desc,id.asc`.
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 0
            default: 100
            maximum: 1000
          description: Max rows returned. Values above 1000 are capped at 1000.
        - in: query
          name: offset
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
          description: Number of rows to skip.
        - in: header
          name: Prefer
          required: false
          schema:
            type: string
          description: Use `count=exact` to request an exact filtered row count.
      responses:
        "200":
          description: Matching rows
          headers:
            Content-Range:
              description: Returned when `Prefer: count=exact` is requested.
              schema:
                type: string
              example: 0-99/327
            Preference-Applied:
              description: Returned when a recognized Prefer directive is applied.
              schema:
                type: string
              example: count=exact
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QueryResponse"
              examples:
                rows:
                  summary: Query result rows
                  value:
                    data:
                      - id: 1
                        title: Fairy Tale
                        price: 23.54
                      - id: 2
                        title: "The Bookstore Sisters: A Short Story"
                        price: 1.99
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/query/books?limit=100&offset=0
                        method: GET
                      first:
                        href: https://www.agentspapi.com/api/v1/query/books?limit=100&offset=0
                        method: GET
                      next:
                        href: https://www.agentspapi.com/api/v1/query/books?limit=100&offset=100
                        method: GET
                    meta:
                      request_id: 2d172d8f-4c9a-4d7d-a6b3-65ff746f41be
                      contract_version: "2026-03-04"
                      table_name: books
                      limit: 100
                      offset: 0
                      returned_count: 2
        "400":
          description: Invalid query parameter or filter
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                invalidQuery:
                  summary: Invalid operator
                  value:
                    error:
                      code: invalid_query
                      message: Unsupported operator 'between' for column 'price'
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/query/books?price=between.1
                        method: GET
                    meta:
                      request_id: 9f6ec429-a9dc-4754-b58f-8898050ec68f
                      contract_version: "2026-03-04"
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Unknown table or view
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                notFound:
                  summary: Relation not found
                  value:
                    error:
                      code: not_found
                      message: "Unknown table or view: unknown_table"
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/query/unknown_table
                        method: GET
                    meta:
                      request_id: e9c5f4e6-c088-4cc6-bfd2-0f6d46ecf4f0
                      contract_version: "2026-03-04"
        "409":
          description: Database snapshot is not ready yet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                databaseSyncing:
                  summary: Data sync in progress
                  value:
                    error:
                      code: database_syncing
                      message: We are syncing Amazon data to your secure database
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/query/books
                        method: GET
                    meta:
                      request_id: d315cf8c-b378-4fdc-a0c1-06ebfa09e814
                      contract_version: "2026-03-04"
        "429":
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: Seconds to wait before retrying the request.
              schema:
                type: integer
                minimum: 1
              example: 60
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                rateLimitExceeded:
                  summary: Per-key API throttle exceeded
                  value:
                    error:
                      code: rate_limit_exceeded
                      message: Rate limit exceeded
                    links:
                      self:
                        href: https://www.agentspapi.com/api/v1/query/books
                        method: GET
                    meta:
                      request_id: 1707d102-05e6-4bb9-a3f2-e17dbf81fa3a
                      contract_version: "2026-03-04"
