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

# List a site's fragments

> Every fragment of the site, active and paused: references in byte order (uppercase before lowercase), fragments without a reference last, then by id. Complete: no pagination.



## OpenAPI

````yaml /openapi-management.json get /v1/sites/{domain}/fragments
openapi: 3.1.0
info:
  title: doubleshift management API
  version: v1
  description: >-
    The management API writes the objects a publisher organisation is made of —
    sites, fragments, the site default, routing rules, card eligibility and
    delivery API keys — with the same rules and the same error messages as the
    console. It is a separate contract from the fragment endpoint
    (`openapi.json`): another credential, and no card serving. `info.version`
    names the contract (`/v1`), not a console release. Guide:
    https://docs.shftd2.com/management-api


    **Host.** `https://api.shftd2.com` only, paths under `/v1`. The console host
    `app.shftd2.com` answers `404` on them.


    **Authentication.** `Authorization: Bearer ds_mgmt_…`: a management token,
    created by an owner in the console (**Settings → Management tokens**) and
    shown once. A token acts on its whole organisation. Cookies are never read.
    A delivery API key (`ds_live_…`) is refused here, and a management token is
    refused by the fragment endpoint.


    **Requests.** Every PUT, POST and DELETE sends `Content-Type:
    application/json` (parameters such as `charset` allowed) and a JSON object —
    `{}` for a DELETE. The body is capped at 262,144 bytes, counted on the raw
    bytes (a UTF-8 byte order mark included) before any parsing: over the cap,
    `400 body_too_large`. Unknown fields are refused (`400 unknown_field`),
    nested ones included. A GET takes no body.


    **Responses.** JSON, with `Cache-Control: private, no-store` and
    `RateLimit-Policy` on every response, success or error. Lists are `{"items":
    [...]}` and complete: there is no pagination. Errors are `{"error": {"code",
    "message", "field"?, "retry_after"?}}`. A resource that does not exist and
    one that belongs to another organisation get the same `404`.


    **Order of checks.** Token and limits (`401`, `429`); then the body: media
    type, size, JSON, unknown fields (`400`), then its shape (`422`); then the
    addressed site, card or key (`404`); then what depends on stored data
    (`403`, `409`, `422`). Nothing is written before every check has passed.


    **Limits.** Per token: 120 requests per minute, of which at most 60 writes
    (PUT, POST, DELETE). Per client IP address: 30 failed authentications per
    minute (no token, or a malformed, unknown, revoked or expired one), and 600
    requests per minute presenting a well-formed token. Over a limit: `429
    rate_limited` with `Retry-After: 60`, and nothing is written. The counters
    are kept per Cloudflare location, so the limits are approximate, and no
    remaining count is sent.
servers:
  - url: https://api.shftd2.com
    description: >-
      The machine host. The management API exists on this host only; there is no
      alias.
security:
  - bearerAuth: []
tags:
  - name: Account
    description: The organisation a token acts on.
  - name: Sites
    description: Sites, addressed by domain.
  - name: Fragments
    description: Fragments, addressed by site domain and reference.
  - name: Site default
    description: The fragment a page resolves to when no routing rule matches.
  - name: Routing rules
    description: Paths that resolve to a fragment of the site.
  - name: Cards
    description: Cards, read-only through this API.
  - name: Eligibility
    description: >-
      The fragments a card is eligible on. Several cards can be eligible on the
      same fragment.
  - name: API keys
    description: Delivery API keys for the fragment endpoint.
paths:
  /v1/sites/{domain}/fragments:
    parameters:
      - $ref: '#/components/parameters/Domain'
    get:
      tags:
        - Fragments
      summary: List a site's fragments
      description: >-
        Every fragment of the site, active and paused: references in byte order
        (uppercase before lowercase), fragments without a reference last, then
        by id. Complete: no pagination.
      operationId: listFragments
      responses:
        '200':
          description: The fragments.
          headers:
            Cache-Control:
              $ref: '#/components/headers/CacheControl'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FragmentList'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: No site of this organisation has this domain.
          headers:
            Cache-Control:
              $ref: '#/components/headers/CacheControl'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimitPolicy'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                not_found:
                  value:
                    error:
                      code: not_found
                      message: not found
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/Internal'
      x-codeSamples:
        - lang: bash
          label: curl
          source: >-
            curl -sS
            "https://api.shftd2.com/v1/sites/news-site.example/fragments" \
              -H "Authorization: Bearer $DS_MANAGEMENT_TOKEN"
components:
  parameters:
    Domain:
      name: domain
      in: path
      required: true
      description: >-
        The site's bare domain, normalized like the console form (trimmed,
        lowercase). `www.news-site.example` and `news-site.example` are two
        different sites. A domain that is not a site of this organisation —
        absent, another organisation's, or not a valid domain — is `404`, except
        on `PUT /v1/sites/{domain}`, which creates the site and answers `422`
        for an invalid domain.
      schema:
        type: string
      example: news-site.example
  headers:
    CacheControl:
      description: On every response of this API.
      schema:
        type: string
        const: private, no-store
    RateLimitPolicy:
      description: >-
        On every response of this API: 120 requests and 60 writes per 60 seconds
        per token (IETF draft ratelimit-headers syntax). No remaining count is
        sent.
      schema:
        type: string
        const: '"token";q=120;w=60, "write";q=60;w=60'
    WWWAuthenticate:
      description: On every 401.
      schema:
        type: string
        const: Bearer realm="doubleshift"
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
        const: 60
  schemas:
    FragmentList:
      type: object
      required:
        - items
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Fragment'
      example:
        items:
          - id: frg_examplefr1
            site_id: sit_examplesite1
            domain: news-site.example
            ref: /1234567/news-site/organic/politics
            name: Politics
            description: null
            lang: en
            key_values:
              section:
                - politics
            status: active
            created_at: '2026-09-26T09:00:00.000Z'
          - id: frg_examplefr2
            site_id: sit_examplesite1
            domain: news-site.example
            ref: /1234567/news-site/organic/sports
            name: Sports
            description: Sports section
            lang: en
            key_values: {}
            status: paused
            created_at: '2026-09-26T09:00:00.000Z'
    Error:
      type: object
      description: >-
        Every error of this API. Like every response, it carries `Cache-Control:
        private, no-store` and `RateLimit-Policy: "token";q=120;w=60,
        "write";q=60;w=60`.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unsupported_media_type
                - body_too_large
                - invalid_json
                - unknown_field
                - missing_token
                - invalid_token
                - platform_card
                - not_found
                - conflict
                - validation
                - rate_limited
                - internal
              description: Stable, machine-readable code. Branch on it, not on `message`.
            message:
              type: string
              description: >-
                Human-readable explanation, the console wording where the
                console has one. May change.
            field:
              type: string
              description: >-
                The field at fault, nested ones included
                (`routes[3].path_prefix`, `fragments[0].ref`). Present on
                `unknown_field`, `validation` and `conflict`; absent otherwise.
            retry_after:
              type: integer
              const: 60
              description: Seconds to wait. Present on `rate_limited` only.
      example:
        error:
          code: validation
          message: Choose a fragment of this site
          field: routes[0].ref
    Fragment:
      type: object
      description: 'A fragment: one card slot on a site, addressed by its reference.'
      required:
        - id
        - site_id
        - domain
        - ref
        - name
        - description
        - lang
        - key_values
        - status
        - created_at
      properties:
        id:
          type: string
          description: Stable fragment id (`frg_…`). Never changes.
        site_id:
          type: string
          description: The site id (`sit_…`).
        domain:
          type: string
          description: The site domain.
        ref:
          type:
            - string
            - 'null'
          description: >-
            The fragment reference. Null for a fragment created in the console
            without one: it is listed, but this API cannot write it, target it
            with a rule, or make a card eligible on it.
        name:
          type: string
          description: The fragment name.
        description:
          type:
            - string
            - 'null'
          description: The description, or null.
        lang:
          type: string
          description: 'The fragment language: `fr`, `en`, `de`, `es` or `it`.'
        key_values:
          $ref: '#/components/schemas/KeyValues'
        status:
          type: string
          enum:
            - active
            - paused
          description: >-
            `paused`: every page that resolves to this fragment answers `204` on
            the fragment endpoint.
        created_at:
          type: string
          format: date-time
          description: Creation time, UTC.
      example:
        id: frg_examplefr2
        site_id: sit_examplesite1
        domain: news-site.example
        ref: /1234567/news-site/organic/sports
        name: Sports
        description: Sports section
        lang: en
        key_values: {}
        status: paused
        created_at: '2026-09-26T09:00:00.000Z'
    KeyValues:
      type: object
      description: >-
        Legacy targeting key-values, `{"key": ["value", …]}`; `{}` when none.
        Keys match `^[a-z0-9_-]+$` exactly (not trimmed; `__proto__` is
        refused). Each key has a non-empty list of strings; each value is
        trimmed, and must then be non-empty and without commas or line breaks.
      propertyNames:
        pattern: ^[a-z0-9_-]+$
        not:
          const: __proto__
      additionalProperties:
        type: array
        minItems: 1
        items:
          type: string
          minLength: 1
      example:
        section:
          - politics
  responses:
    Unauthorized:
      description: >-
        `missing_token`: no `Authorization: Bearer` header. `invalid_token`:
        anything else that is not a live management token of an organisation —
        malformed, unknown, revoked or expired, or a delivery API key
        (`ds_live_…`). Cookies are never read. Carries `WWW-Authenticate: Bearer
        realm="doubleshift"`.
      headers:
        Cache-Control:
          $ref: '#/components/headers/CacheControl'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
        WWW-Authenticate:
          $ref: '#/components/headers/WWWAuthenticate'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missing_token:
              value:
                error:
                  code: missing_token
                  message: >-
                    missing management token — send "Authorization: Bearer
                    ds_mgmt_…"
            invalid_token:
              value:
                error:
                  code: invalid_token
                  message: invalid management token
    RateLimited:
      description: >-
        A limit was reached (per token: 120 requests or 60 writes per minute;
        per IP address: 30 failed authentications or 600 requests presenting a
        well-formed token per minute). Nothing was written. Carries
        `Retry-After: 60`, and `retry_after: 60` in the body: wait that long
        before retrying.
      headers:
        Cache-Control:
          $ref: '#/components/headers/CacheControl'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: rate limited — retry after 60 seconds
              retry_after: 60
    Internal:
      description: An unexpected server error. The message is fixed and carries no detail.
      headers:
        Cache-Control:
          $ref: '#/components/headers/CacheControl'
        RateLimit-Policy:
          $ref: '#/components/headers/RateLimitPolicy'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            internal:
              value:
                error:
                  code: internal
                  message: internal error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A management token: `ds_mgmt_` followed by 40 lowercase hexadecimal
        characters, created by an owner in **Settings → Management tokens**.
        Opaque: send it as is, in the `Authorization` header only.

````