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

# Re-pin a subscription's schema major

> Narrowly re-pins a subscription's `schema_major` — the only mutable field. Send exactly one field, `schema_major`: an integer `>= 1` re-pins to the versioned topic; `null` clears the pin to follow-base. Any other field, an out-of-range value, or an empty body is rejected with `422 validation_error` (out-of-scope fields are rejected, not ignored). A re-pin is not a destination change: it does not reset the verification state and echoes no secret. Success returns `200` with no body.



## OpenAPI

````yaml en/openapi/v3-current/streaming-hub.yaml patch /v1/subscriptions/{id}
openapi: 3.1.0
info:
  title: Lerian Streaming Hub API
  version: v1.0.0
  contact:
    email: contact@lerian.studio
    name: Lerian Studio
    url: https://lerian.studio
  license:
    name: Lerian Studio General License
  description: >-
    The Streaming Hub control-plane API. Streaming Hub is Lerian's managed
    event-delivery edge: it consumes CloudEvents from the platform's internal
    streaming backbone and fans them out to a tenant's own external destinations
    — webhooks, Amazon SQS, RabbitMQ, Amazon EventBridge, or a pull inbox. This
    API lets a tenant browse the manifest-fed event catalog, create and manage
    delivery subscriptions, verify and rotate their credentials, read delivery
    health, and pull entitled events.


    Errors use a flat `{"error":"<token>"}` envelope (a low-cardinality,
    machine-readable token — never RFC 9457 problem+json). Mutating operations
    require an `X-Idempotency` header for at-most-once semantics; a replayed
    request returns the original response byte-for-byte with
    `X-Idempotency-Replayed: true`. The catalog and the pull events surface are
    tenant-scoped through the bearer JWT; the operational probe endpoints
    (`/healthz`, `/readyz`, `/version`, `/runtime`, `/metrics`) are
    unauthenticated. Streaming Hub is closed source under the Lerian Studio
    General License.
servers:
  - url: https://streaming-hub.sandbox.lerian.net
security:
  - BearerAuth: []
tags:
  - name: Catalog
    description: Browse the manifest-fed catalog of event types available for subscription.
  - name: Subscriptions
    description: >-
      Create, read, update, and delete delivery subscriptions, and drive the
      destination verification lifecycle (ping, verify, credential, delegated
      grant, secret rotation, health).
  - name: Event Delivery
    description: >-
      Pull entitled events for a pull-sink subscription
      (cursor-as-acknowledgment read).
  - name: Admin
    description: Cross-tenant operator forensics. Requires an operator authorization scope.
  - name: Operational
    description: Unauthenticated liveness, readiness, build, runtime, and metrics probes.
paths:
  /v1/subscriptions/{id}:
    patch:
      tags:
        - Subscriptions
      summary: Re-pin a subscription's schema major
      description: >-
        Narrowly re-pins a subscription's `schema_major` — the only mutable
        field. Send exactly one field, `schema_major`: an integer `>= 1` re-pins
        to the versioned topic; `null` clears the pin to follow-base. Any other
        field, an out-of-range value, or an empty body is rejected with `422
        validation_error` (out-of-scope fields are rejected, not ignored). A
        re-pin is not a destination change: it does not reset the verification
        state and echoes no secret. Success returns `200` with no body.
      operationId: updateSubscriptionSchemaMajor
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchSubscriptionRequest'
      responses:
        '200':
          description: The re-pin succeeded (no body).
          headers:
            X-Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
        '400':
          $ref: '#/components/responses/BadRequestOrMissingIdempotency'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/IdempotencyConflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - BearerAuth: []
components:
  parameters:
    SubscriptionId:
      name: id
      in: path
      required: true
      description: The unique identifier of the subscription (UUIDv7).
      schema:
        type: string
        format: uuid
    IdempotencyKey:
      name: X-Idempotency
      in: header
      required: true
      description: >-
        A client-chosen unique key that makes this mutation at-most-once. A
        mutation sent without it is rejected before any write with `400
        missing_idempotency_key`. Reusing the same key with an identical request
        replays the original response byte-for-byte (with
        `X-Idempotency-Replayed: true`); reusing it with a different request
        body returns `409 idempotency_conflict`. To re-drive a corrected
        request, mint a new key.
      schema:
        type: string
  schemas:
    PatchSubscriptionRequest:
      type: object
      additionalProperties: false
      description: >-
        The narrow re-pin body. Exactly one field, `schema_major`: an integer
        `>= 1` re-pins to the versioned topic; `null` clears the pin. Any other
        field or an empty body is rejected with `422 validation_error`.
      properties:
        schema_major:
          type:
            - integer
            - 'null'
          description: >-
            The schema major to pin, or `null` to follow the base topic. A value
            `< 1` is rejected.
          examples:
            - 2
      required:
        - schema_major
    Error:
      type: object
      additionalProperties: false
      description: >-
        The flat error envelope used across the `/v1` and `/admin` surfaces. It
        carries a single low-cardinality, machine-readable token and never leaks
        secret material or internal detail. (A `403` from the authorization
        decision point is the one exception — its body is plain text.)
      properties:
        error:
          type: string
          description: The machine-readable error token.
          examples:
            - not_found
      required:
        - error
  headers:
    IdempotencyReplayed:
      description: >-
        Present and set to `true` when this response is a replay of a previously
        committed request carrying the same `X-Idempotency` key (the handler did
        not run again).
      schema:
        type: string
        enum:
          - 'true'
  responses:
    BadRequestOrMissingIdempotency:
      description: >-
        The request body is malformed (`bad_request`) or the required
        `X-Idempotency` header is missing (`missing_idempotency_key`, rejected
        before any write).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: >-
        Authentication failed, or there is no trusted tenant context. `error` is
        `unauthorized` (uniform body — no reason is leaked).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        The authorization decision point denied the request. The body is plain
        text (not the JSON error envelope).
      content:
        text/plain:
          schema:
            type: string
    NotFound:
      description: >-
        The resource is absent, soft-deleted, or owned by another tenant — a
        uniform `error` of `not_found` (no existence oracle).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    IdempotencyConflict:
      description: >-
        An in-flight duplicate, or the same `X-Idempotency` key was reused with
        a different request fingerprint — `error` is `idempotency_conflict`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ValidationError:
      description: A caller-correctable shape fault — `error` is `validation_error`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: >-
        An infrastructure fault. `error` is `internal_error` (sanitized; detail
        is logged, never returned).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        A bearer JWT issued by plugin-auth (lib-auth). The tenant identity is
        resolved from the validated token claims; the `/v1` surface never reads
        a tenant from the body, path, or query. Machine callers obtain a token
        via the plugin-auth client-credentials flow. The `/admin` surface
        authorizes against an operator scope and carries no tenant context.

````