> ## Documentation Index
> Fetch the complete documentation index at: https://developers.tassyir.io/llms.txt
> Use this file to discover all available pages before exploring further.

# ID-token public keys (JWKS)

> Verify the ID token your embedded page receives: pick the key by `kid`, require `alg: EdDSA`, `iss = https://api.tassyir.io/apps`, `aud = <your client_id>`, and `exp`/`nbf` with at most 30 s of clock skew.



## OpenAPI

````yaml /openapi/openapi.2026-10.json get /apps/.well-known/jwks.json
openapi: 3.1.0
info:
  title: Tassyir Admin API
  version: 2026-10
  summary: >-
    The API installed apps call to read and change a Tassyir business, and the
    webhooks they receive.
  description: >-
    Version `2026-10` of the API installed Tassyir apps call. The routes live
    under `/apps/2026-10/`; the token endpoint and the key documents under
    `/apps/`. Guides, and a page for every error code:
    https://developers.tassyir.io.


    **Authentication.** `Authorization: Bearer tsy_at_…` from `POST
    /apps/oauth/token`. An app acts as a team member of the business: it reads
    and writes only what its granted scopes allow, only in the stores the
    merchant gave it, under the merchant's plan.


    **Conventions.** JSON fields are camelCase; ids are strings; times are ISO
    8601 UTC; money is a decimal string (`"2500.00"`) with a `currency` field,
    never a number. A list answers `{ data, nextCursor }`, newest first,
    keyset-paged: `limit` 1 to 100 (default 50), `cursor` = the previous
    `nextCursor`. A single resource answers `{ data }`. `fields` trims a
    resource to the named top-level fields. Fields without
    `read_customer_contact` (buyer name, phones, address, notes) are omitted,
    not nulled. Every answer is `Cache-Control: no-store`.


    **Writes.** Send an `Idempotency-Key` to make a write safe to retry (24
    hours per installation).


    **Errors.** `application/problem+json` with a stable `code`, a `fix`
    sentence, the `docs` page of the code and a `requestId`. Each operation
    lists every code it can answer; `x-tassyir-errors` lists every code a
    problem can carry, with its title, statuses and `fix`. HTTP 460
    `STORE_SCOPE_FORBIDDEN` means a store outside the installation's stores.


    **Rate limits.** A leaky bucket per installation, by default 40 requests
    refilled at 4 a second: every answer carries `RateLimit-Limit`,
    `RateLimit-Remaining` and `RateLimit-Reset`; a refusal is 429 `RATE_LIMITED`
    with `Retry-After`. All the apps of one business also share a ceiling, by
    default 20 requests a second: 429 `BUSINESS_RATE_LIMITED` with
    `Retry-After`. An API process that is already running its maximum of app
    requests answers 503 `API_BUSY` with `Retry-After`, having done nothing.


    **Webhooks.** Signed Standard Webhooks deliveries (`v1a`, Ed25519), one per
    topic below; verify them with `GET /apps/webhook-keys`.
servers:
  - url: https://api.tassyir.io
security:
  - appAccessToken: []
tags:
  - name: Authentication
    description: Tokens and the public keys apps verify with.
  - name: Business
    description: The business the app is installed on.
  - name: Orders
    description: Orders, their comments and the cancel reasons.
  - name: Products
    description: Products and their variants.
  - name: Collections
    description: Collections and their members.
  - name: Inventory
    description: Stock levels.
  - name: Customers
    description: The buyers behind the orders.
  - name: Stores
    description: The installation's stores.
  - name: Delivery
    description: Delivery agents and fee groups (never credentials).
  - name: Data
    description: >-
      Typed values the app keeps on the business, its stores, products, orders
      and customers, under keys its manifest declares.
  - name: Images
    description: >-
      Images re-hosted on the Tassyir CDN, for the product and collection
      writes.
  - name: Bulk exports
    description: >-
      A whole list (orders, products, customers) as one JSON Lines file, instead
      of paging through it.
  - name: Webhooks
    description: What Tassyir POSTs to the app.
paths:
  /apps/.well-known/jwks.json:
    get:
      tags:
        - Authentication
      summary: ID-token public keys (JWKS)
      description: >-
        Verify the ID token your embedded page receives: pick the key by `kid`,
        require `alg: EdDSA`, `iss = https://api.tassyir.io/apps`, `aud = <your
        client_id>`, and `exp`/`nbf` with at most 30 s of clock skew.
      operationId: getIdTokenKeys
      responses:
        '200':
          description: Every published key, inactive ones included.
          headers:
            Cache-Control:
              description: '`public, max-age=3600`: refetch on an unknown key.'
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JsonWebKeySet'
        '503':
          description: '`APPS_KEYS_NOT_CONFIGURED`: this server signs nothing yet.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KeysNotConfigured'
      security: []
components:
  schemas:
    JsonWebKeySet:
      type: object
      properties:
        keys:
          type: array
          items:
            type: object
            properties:
              kty:
                type: string
                const: OKP
              crv:
                type: string
                const: Ed25519
              x:
                type: string
                description: The raw public key, base64url.
              kid:
                type: string
              alg:
                type: string
                const: EdDSA
              use:
                type: string
                const: sig
            required:
              - kty
              - crv
              - x
              - kid
              - alg
              - use
      required:
        - keys
    KeysNotConfigured:
      type: object
      properties:
        code:
          type: string
          const: APPS_KEYS_NOT_CONFIGURED
        message:
          type: string
        keySet:
          type: string
          enum:
            - id_token
            - webhook
        requestId:
          type: string
      required:
        - code
        - message
        - keySet
  securitySchemes:
    appAccessToken:
      type: http
      scheme: bearer
      bearerFormat: tsy_at_<43 base62>
      description: >-
        An app access token from `POST /apps/oauth/token`, valid 1 hour. An
        offline token acts as the app; an online token acts as the app on behalf
        of one dashboard user (the intersection of both permission sets).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.