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

> ## Agent Instructions
> Follow the content contract in AGENTS.md.
> Treat text as the canonical explanation; video and screenshots enhance it.
> Do not publish unverified product behavior or duplicate an existing canonical article.

# Write landing page labels, or check them with dryRun

> Stores one label card per landing page: industry, product form, target gender, target age, price band and page kind, each a value of the named list version or null. StefanBrain computes the landing key from each raw URL and checks each value against its list. Every item gets its own result, in order: a refused item names its reason and does not stop the others, and an unknown value returns the valid values. Idempotent: the same request sent again answers `already_stored`. `dryRun: true` runs every check, returns each landing key, and writes nothing. A stored card is never edited, and it is not shown in benchmarks until StefanBrain activates its label version. 1 to 200 items in a UTF-8 body of at most 32 MB. Rate-limited, never metered. Requires the `tools` scope and the account's own landing_page_label_writer grant.



## OpenAPI

````yaml /developers/openapi/stefanbrain-v1.json post /api/developers/v1/meta/landing-page-labels
openapi: 3.1.0
info:
  title: StefanBrain Developer API
  version: 1.0.0
  description: >-
    REST access to StefanBrain agent runs, tools, and jobs. Authenticate with an
    API key from Settings → Developers. REST usage bills your prepaid API wallet
    at the published per-token rates (see
    https://docs.stefanbrain.com/developers/pricing); the MCP endpoint
    (/api/developers/v1/mcp, not described here) is member pricing from your
    plan pool. Human documentation: https://docs.stefanbrain.com/developers
servers:
  - url: https://stefanbrain.com
security:
  - bearerAuth: []
  - apiKeyHeader: []
tags:
  - name: tools
    description: Directly invocable StefanBrain tools.
  - name: jobs
    description: Long-running tool jobs (poll for results).
  - name: runs
    description: Agentic chat runs with event streams.
  - name: files
    description: Workspace files agent runs produced in a chat.
  - name: media
    description: 'Stored Meta ad media facts: video transcripts on demand.'
  - name: feedback
    description: >-
      Tell StefanBrain where the API got in your way, and read the team's
      replies.
  - name: meta
    description: 'Meta landing page labels: the label lists, and the one checked write.'
paths:
  /api/developers/v1/meta/landing-page-labels:
    post:
      tags:
        - meta
      summary: Write landing page labels, or check them with dryRun
      description: >-
        Stores one label card per landing page: industry, product form, target
        gender, target age, price band and page kind, each a value of the named
        list version or null. StefanBrain computes the landing key from each raw
        URL and checks each value against its list. Every item gets its own
        result, in order: a refused item names its reason and does not stop the
        others, and an unknown value returns the valid values. Idempotent: the
        same request sent again answers `already_stored`. `dryRun: true` runs
        every check, returns each landing key, and writes nothing. A stored card
        is never edited, and it is not shown in benchmarks until StefanBrain
        activates its label version. 1 to 200 items in a UTF-8 body of at most
        32 MB. Rate-limited, never metered. Requires the `tools` scope and the
        account's own landing_page_label_writer grant.
      operationId: writeMetaLandingPageLabels
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LandingPageLabelWriteRequest'
      responses:
        '200':
          description: One result per item, in the order the items were sent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LandingPageLabelWriteResponse'
        '400':
          description: >-
            The body is not valid UTF-8 or not a JSON object (code
            invalid_json), or breaks the request schema (code
            invalid_landing_page_label_request; the message names the field).
            Nothing was written.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, invalid, or revoked API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            Suspended key, missing plan access, key scoped away from this
            surface (code api_key_scope_forbidden), or an account without the
            landing_page_label_writer grant (code
            landing_page_label_writer_required).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No label list has this version (code taxonomy_version_not_found).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            labelVersion is bound to another taxonomyVersion, model or
            promptVersion (code label_version_mismatch). Send the reading under
            a new labelVersion. Nothing was written.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: >-
            A body over 32 MB (code request_too_large). Send fewer items in each
            request. Nothing was written.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            Rate limited (codes request_per_minute, request_per_minute_user,
            request_per_day, user_throttled, user_suspended; Retry-After header
            when the limit has a reset time, plus limits, observed counts, and
            reset_at in the body), the runtime has no capacity to start a turn
            right now (code runtime_capacity_busy, Retry-After: 5), wallet
            exhausted (code api_wallet_exhausted), key budget exhausted (code
            api_key_budget_exhausted), or the plan's monthly usage pool spent
            for OAuth-token traffic (code monthly_usage_limit_reached).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    LandingPageLabelWriteRequest:
      type: object
      properties:
        labelVersion:
          description: >-
            The name of this way of reading pages. Its first write binds it to
            taxonomyVersion, model and promptVersion; a later request under the
            same name with another of them is refused. A name starts with
            `estate-`: StefanBrain keeps every other name for its own readings.
          type: string
          pattern: ^estate-[a-z0-9._-]{1,57}$
        taxonomyVersion:
          description: The list version the labels are values of.
          type: integer
          minimum: 1
          maximum: 2147483647
        model:
          description: The model that made the labels.
          type: string
          minLength: 1
          maxLength: 200
        promptVersion:
          description: The version of the prompt that made the labels.
          type: string
          minLength: 1
          maxLength: 200
        sourceArtifactSha256:
          description: SHA-256 of the file the items came from.
          type: string
          pattern: ^[0-9a-f]{64}$
        dryRun:
          description: >-
            true checks every item and returns each landing key, and writes
            nothing.
          type: boolean
        items:
          description: One item per landing page.
          minItems: 1
          maxItems: 200
          type: array
          items:
            type: object
            properties:
              landingUrl:
                description: >-
                  The ad's own raw landing URL, exactly as the ad holds it.
                  StefanBrain computes the landing key from it. Over 8,192
                  characters it is refused for its item (`url_too_long`), never
                  cut.
                type: string
              inputDigest:
                description: >-
                  SHA-256 of what the reading read. With the page and the label
                  version it is the card's identity: the same three with the
                  same labels is a repeat.
                type: string
                pattern: ^[0-9a-f]{64}$
              industry:
                description: >-
                  A value of the industry list of this list version, or null
                  where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              productForm:
                description: >-
                  A value of the product_form list of this list version, or null
                  where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              targetGender:
                description: >-
                  A value of the target_gender list of this list version, or
                  null where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              targetAge:
                description: >-
                  A value of the target_age list of this list version, or null
                  where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              priceBand:
                description: >-
                  A value of the price_band list of this list version, or null
                  where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              pageKind:
                description: >-
                  A value of the page_kind list of this list version, or null
                  where the page does not say.
                anyOf:
                  - type: string
                  - type: 'null'
              evidence:
                description: >-
                  What the reading found beside the labels. Stored with the card
                  and never shown to benchmark readers. As stored (snake_case
                  keys, null fields left out, PostgreSQL jsonb text) it is at
                  most 8,192 bytes. A larger one is refused for its item
                  (`evidence_too_long`), never cut.
                type: object
                properties:
                  brand:
                    description: The brand the page sells.
                    anyOf:
                      - type: string
                      - type: 'null'
                  productName:
                    description: The product the page sells.
                    anyOf:
                      - type: string
                      - type: 'null'
                  categoryText:
                    description: The page's market in the source's own words.
                    anyOf:
                      - type: string
                      - type: 'null'
                  summary:
                    description: What the page is about.
                    anyOf:
                      - type: string
                      - type: 'null'
                  proposedIndustry:
                    description: >-
                      The market the reading names when the industry is
                      `<sector>.other`.
                    anyOf:
                      - type: string
                      - type: 'null'
                  viaHop:
                    description: >-
                      How many pages after the ad's own page the product was
                      found on.
                    anyOf:
                      - type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      - type: 'null'
                required:
                  - brand
                  - productName
                  - categoryText
                  - summary
                  - proposedIndustry
                  - viaHop
                additionalProperties: false
            required:
              - landingUrl
              - inputDigest
              - industry
              - productForm
              - targetGender
              - targetAge
              - priceBand
              - pageKind
              - evidence
            additionalProperties: false
      required:
        - labelVersion
        - taxonomyVersion
        - model
        - promptVersion
        - sourceArtifactSha256
        - dryRun
        - items
      additionalProperties: false
    LandingPageLabelWriteResponse:
      type: object
      properties:
        results:
          description: One result per item, in the order the items were sent.
          type: array
          items:
            anyOf:
              - type: object
                properties:
                  outcome:
                    description: >-
                      `stored`: a new card. `would_store`: a dry run of an item
                      a write would store. `already_stored`: the same page,
                      label version, input digest and labels are stored; nothing
                      changed. `replaced`: the same card is stored, and a newer
                      card of the page in this label version replaced it; send
                      the labels as a new reading (another inputDigest) to say
                      them again. `conflict`: the same page, label version and
                      input digest are stored with other labels; nothing was
                      written.
                    type: string
                    enum:
                      - stored
                      - would_store
                      - already_stored
                      - replaced
                      - conflict
                  landingKeySha256:
                    description: >-
                      SHA-256 of the page's landing key: the URL as StefanBrain
                      normalizes it. Two raw URLs with the same value are the
                      same page.
                    type: string
                    pattern: ^[0-9a-f]{64}$
                required:
                  - outcome
                  - landingKeySha256
              - type: object
                properties:
                  outcome:
                    type: string
                    const: refused
                  reason:
                    description: >-
                      `url_too_long`: landingUrl is over the limit.
                      `no_landing_page`: landingUrl has no landing key (it is
                      empty, or only a query or a fragment).
                    type: string
                    enum:
                      - url_too_long
                      - no_landing_page
                  landingKeySha256:
                    type: 'null'
                required:
                  - outcome
                  - reason
                  - landingKeySha256
              - type: object
                properties:
                  outcome:
                    type: string
                    const: refused
                  reason:
                    description: >-
                      `duplicate_in_request`: two or more items of this request
                      are the same page; none of them is stored. `no_values`:
                      every label is null. `evidence_too_long`: evidence is over
                      the limit.
                    type: string
                    enum:
                      - duplicate_in_request
                      - no_values
                      - evidence_too_long
                  landingKeySha256:
                    description: >-
                      SHA-256 of the page's landing key: the URL as StefanBrain
                      normalizes it. Two raw URLs with the same value are the
                      same page.
                    type: string
                    pattern: ^[0-9a-f]{64}$
                required:
                  - outcome
                  - reason
                  - landingKeySha256
              - type: object
                properties:
                  outcome:
                    type: string
                    const: refused
                  reason:
                    type: string
                    const: unknown_value
                  landingKeySha256:
                    description: >-
                      SHA-256 of the page's landing key: the URL as StefanBrain
                      normalizes it. Two raw URLs with the same value are the
                      same page.
                    type: string
                    pattern: ^[0-9a-f]{64}$
                  field:
                    description: The first label field whose value is not in its list.
                    type: string
                    enum:
                      - industry
                      - productForm
                      - targetGender
                      - targetAge
                      - priceBand
                      - pageKind
                  validValues:
                    description: >-
                      Every value of that list in this list version, in list
                      order.
                    type: array
                    items:
                      type: string
                required:
                  - outcome
                  - reason
                  - landingKeySha256
                  - field
                  - validValues
      required:
        - results
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
          properties:
            message:
              type: string
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - rate_limit_error
                - api_error
                - service_unavailable_error
            code:
              type: string
          additionalProperties: true
      additionalProperties: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Authorization: Bearer stefan_sk_... (API key — bills the API wallet) or
        stefan_oat_... (OAuth member token — bills your plan pool).
    apiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key

````

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