> ## 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.

# Register an AWS delegated grant

> Registers the AWS delegated-grant coordinates for an AWS-sink subscription (`sqs`, `eventbridge`) — the non-secret cross-account delivery role ARN, region, and destination the hub uses at delivery time. This is the write that follows the customer applying the setup-artifacts trust policy in their AWS account. It is write-only: it runs no inline probe and does not change the verification state (a registered grant stays `pending_verification` until a later `verify`). No AWS credential crosses this body. The destination host is validated before the write. A non-AWS sink returns `422 validation_error`.



## OpenAPI

````yaml /pt/openapi/v3-current/streaming-hub.yaml put /v1/subscriptions/{id}/delegated-grant
openapi: 3.1.0
info:
  title: Lerian Streaming Hub API
  version: 1.2.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.


    An RFC 9457 `application/problem+json` error body carries `title` and
    `status`. An error the hub raises adds `type`, `detail`, and a stable
    low-cardinality `code` you can branch on; a request the framework rejects
    before the operation runs, such as a malformed or schema-invalid one,
    carries no `code`. 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.
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: Dashboard
    description: >-
      The read-only operational dashboard: a consistent snapshot of ingestion,
      push delivery, and pull eligibility, plus the paged list of subscriptions
      that need attention. It never consumes events and never returns a secret.
  - 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}/delegated-grant:
    put:
      tags:
        - Subscriptions
      summary: Register an AWS delegated grant
      description: >-
        Registers the AWS delegated-grant coordinates for an AWS-sink
        subscription (`sqs`, `eventbridge`) — the non-secret cross-account
        delivery role ARN, region, and destination the hub uses at delivery
        time. This is the write that follows the customer applying the
        setup-artifacts trust policy in their AWS account. It is write-only: it
        runs no inline probe and does not change the verification state (a
        registered grant stays `pending_verification` until a later `verify`).
        No AWS credential crosses this body. The destination host is validated
        before the write. A non-AWS sink returns `422 validation_error`.
      operationId: putSubscriptionDelegatedGrant
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegatedGrantRequest'
      responses:
        '200':
          description: >-
            The grant was persisted (no body; the verification state is
            unchanged).
          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':
          description: >-
            The request is caller-correctable. `code` names the fault, for
            example `validation_error` (a missing `roleArn` / `region` /
            `destination`, or a non-AWS sink) or `endpoint_blocked` (the
            destination host resolved to a blocked, private, or metadata
            address).
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
        '504':
          $ref: '#/components/responses/GatewayTimeout'
      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:
    DelegatedGrantRequest:
      type: object
      additionalProperties: false
      description: >-
        The non-secret AWS delegated-grant coordinates. No AWS credential
        crosses this body — the role is assumed per delivery, guarded by the
        separately minted `ExternalId`.
      properties:
        roleArn:
          type: string
          description: >-
            The cross-account delivery role ARN Streaming Hub assumes at
            delivery time.
          examples:
            - arn:aws:iam::444455556666:role/streaming-hub-delegated-delivery
        region:
          type: string
          description: The AWS region of the destination.
          examples:
            - us-east-1
        destination:
          type: string
          description: >-
            The resolved destination (queue URL or event-bus ARN).
            SSRF-validated before the write.
          examples:
            - https://sqs.us-east-1.amazonaws.com/444455556666/orders
      required:
        - roleArn
        - region
        - destination
    Error:
      type: object
      description: >-
        RFC 9457 `application/problem+json` document. An error the hub raises
        carries `detail` and the stable `code` a client branches on; a request
        the framework rejects before the operation runs carries no `code`.
      properties:
        type:
          type: string
          format: uri
          description: >-
            A stable, versioned URI identifying the problem type
            (`https://errors.lerian.studio/v1/<code>`).
          examples:
            - https://errors.lerian.studio/v1/not_found
        title:
          type: string
          description: A short human-readable summary — the HTTP status text.
          examples:
            - Not Found
        status:
          type: integer
          description: The HTTP status code, mirrored in the body.
          examples:
            - 404
        detail:
          type: string
          description: A human explanation of this specific occurrence.
          examples:
            - subscription not found
        code:
          type: string
          description: >-
            The stable, low-cardinality, machine-readable token a client
            branches on (for example `not_found`, `unauthorized`,
            `idempotency_conflict`, `validation_error`). Absent when the
            framework rejects the request before the operation runs.
          examples:
            - not_found
        instance:
          type: string
          description: The trace id of the request, when the hub has one.
          examples:
            - 4bf92f3577b34da6a3ce929d0e0e4736
        errors:
          type: array
          description: >-
            When present, the entries name what was refused. On
            `unknown_event_type`, each entry names one refused event type and
            its schema major.
          items:
            type: object
            properties:
              location:
                type: string
                description: The refused field, with its position in a list.
                examples:
                  - event_types/2
              message:
                type: string
                description: Why the hub refused the value.
                examples:
                  - '"transaction.creatd" has no catalog entry at schema major 1'
      required:
        - title
        - status
  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'
    RetryAfter:
      description: The whole seconds to wait before a retry. Always at least `1`.
      schema:
        type: string
        examples:
          - '1'
  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/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: >-
        Authentication failed. `code` names the cause, for example `AUT-0006`
        (no token), `AUT-0007` (an expired, invalid, or malformed token), or
        `unauthorized` (no trusted tenant context).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        The caller is authenticated but is not allowed to make this request.
        `code` names the cause, for example `AUT-1020` (the credential does not
        have the permission; `detail` names the refused `resource:action`) or
        `forbidden`.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: >-
        The resource is absent, soft-deleted, or owned by another tenant — a
        uniform `code` of `not_found` (no existence oracle).
      content:
        application/problem+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 — `code` is `idempotency_conflict`. When
        an earlier request under this key may have committed with no recorded
        outcome, `code` is `idempotency_outcome_unrecorded`: read the resource
        before you send anything again.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: >-
        An infrastructure fault. `code` is `internal_error` and `detail` is
        scrubbed to the static `"internal error"` (the cause is logged, never
        returned). On a mutation that requires `X-Idempotency`, `code` can
        instead be `idempotency_outcome_unrecorded`: the mutation may have
        committed, and its outcome was not recorded. Read the resource before
        you send anything again.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    ServiceUnavailable:
      description: >-
        Access Manager did not decide the request. `code` names the cause, for
        example `AUT-0033`. This is a transient condition, not a denial: wait
        the `Retry-After` seconds, then retry.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
    GatewayTimeout:
      description: >-
        Access Manager did not answer in time. `code` names the cause, for
        example `AUT-1021`. Retry the request.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        A bearer JWT issued by Access Manager. The `/v1` surface never reads a
        tenant from the body, path, or query. Machine callers obtain a token
        with the Access Manager client-credentials flow. The `/admin` surface
        authorizes against an operator scope and carries no tenant context.

````

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