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

> ## Agent Instructions
> Use Stable documentation by default. Honor an explicit Beta request or a URL under /docs/beta/. If the requested version conflicts with the installed CLI package or API origin, clarify the target before writing integration code.
> Pages under /docs/beta/ document Beta; other product pages document Stable. Keep the CLI package, commands, API origin, and credentials within the selected version. State the documentation version in your answer.
> For MCP search, always pass version: Stable or version: Beta. Unfiltered search mixes both versions. For filesystem reads, keep Beta queries under /beta/ and exclude /beta/ from Stable queries; discover paths before reading them.
> The public docs base is https://photon.codes/docs. Convert MCP page paths to public URLs under that base, preserving /beta/ when present. Read https://photon.codes/docs/skill.md for version selection and https://photon.codes/docs/llms.txt for the version indexes.

# Get the project's effective billing terms

> Returns what the selected project is billed on now, per category it holds: the plan as its subscription has it, with any override applied, each fixed charge at the subscription's price and quantity, and resolved entitlements; where the plan comes from; how invoices are paid; the current period and next billing date; and any downgrade or cancellation waiting for the period end. It also returns the credit the paying organization holds on credit notes, such as the unused time of a plan an upgrade replaced; it offsets that organization's next invoices. Supply both organizationId and projectId; the organization must pay for the project. This operation does not change billing.



## OpenAPI

````yaml https://api.photon.codes/openapi.json get /v1/organizations/{organizationId}/billing/projects/{projectId}/terms
openapi: 3.1.0
info:
  title: Photon API
  version: 1.0.0
servers:
  - url: https://api.photon.codes
security: []
paths:
  /v1/organizations/{organizationId}/billing/projects/{projectId}/terms:
    get:
      tags:
        - Organization Billing
      summary: Get the project's effective billing terms
      description: >-
        Returns what the selected project is billed on now, per category it
        holds: the plan as its subscription has it, with any override applied,
        each fixed charge at the subscription's price and quantity, and resolved
        entitlements; where the plan comes from; how invoices are paid; the
        current period and next billing date; and any downgrade or cancellation
        waiting for the period end. It also returns the credit the paying
        organization holds on credit notes, such as the unused time of a plan an
        upgrade replaced; it offsets that organization's next invoices. Supply
        both organizationId and projectId; the organization must pay for the
        project. This operation does not change billing.
      operationId: getEffectiveTerms
      parameters:
        - in: path
          name: organizationId
          required: true
          schema:
            type: string
        - description: The project being billed.
          in: path
          name: projectId
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetEffectiveTermsResponse'
          description: The project's effective billing terms, per category.
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
        '400':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/InvalidArgumentProblem'
          description: 'INVALID_ARGUMENT: Invalid Argument'
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
        '401':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/NotAuthenticatedProblem'
          description: 'NOT_AUTHENTICATED: Not Authenticated'
          headers:
            Link:
              description: Optional related resources.
              schema:
                type: string
            RateLimit:
              description: Optional rate limit information.
              schema:
                type: string
            RateLimit-Policy:
              description: Optional rate limit policy.
              schema:
                type: string
            Retry-After:
              description: Optional retry delay or HTTP date.
              schema:
                type: string
            WWW-Authenticate:
              required: true
              schema:
                type: string
            X-Request-ID:
              description: Application request identifier.
              schema:
                type: string
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/GetEffectiveTermsForbiddenProblem'
          description: >-
            FORBIDDEN: Forbidden; RESOURCE_MISMATCH: Resource Mismatch


            FORBIDDEN: Forbidden; INSUFFICIENT_SCOPE: Insufficient Scope;
            ORGANIZATION_SSO_REQUIRED: Organization SSO Required
          headers:
            Deprecation:
              description: >-
                RFC 9745 structured-field Date at which the operation was or
                will be deprecated: `@` followed by Unix seconds, for example
                `@1767225599`.
              schema:
                pattern: ^@-?[0-9]+$
                type: string
            Idempotent-Replayed:
              description: True when this response was replayed from an earlier attempt.
              schema:
                type: boolean
            Link:
              description: |-
                Links related to lifecycle or remediation documentation.

                Optional related resources.
              schema:
                type: string
            RateLimit:
              description: |-
                Current rate-limit state.

                Optional rate limit information.
              schema:
                type: string
            RateLimit-Policy:
              description: |-
                Rate-limit policy applied by the gateway.

                Optional rate limit policy.
              schema:
                type: string
            Retry-After:
              description: |-
                Delay before retrying, in seconds or as an HTTP date.

                Optional retry delay or HTTP date.
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594 HTTP-date (IMF-fixdate) after which the operation may
                become unavailable, for example `Thu, 31 Dec 2026 23:59:59 GMT`.
              schema:
                pattern: >-
                  ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]{2}
                  (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{4}
                  [0-9]{2}:[0-9]{2}:[0-9]{2} GMT$
                type: string
            X-Request-ID:
              description: |-
                Identifier for this HTTP attempt.

                Application request identifier.
              schema:
                type: string
            X-Trace-ID:
              description: >-
                Trace ID of this request. Sent alongside X-Request-ID when a
                middleware published a trace ID for the request.
              schema:
                pattern: ^(?!0{32}$)[0-9a-f]{32}$
                type: string
        '409':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/FailedPreconditionProblem'
          description: 'FAILED_PRECONDITION: Failed Precondition'
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ValidationFailedProblem'
          description: 'VALIDATION_FAILED: Request Validation Failed'
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
        '500':
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/GetEffectiveTermsInternalServerErrorProblem
          description: |-
            INVALID_AUTH_CONTEXT: Invalid Authentication Context

            INTERNAL_ERROR: Internal Server Error
          headers:
            Deprecation:
              description: >-
                RFC 9745 structured-field Date at which the operation was or
                will be deprecated: `@` followed by Unix seconds, for example
                `@1767225599`.
              schema:
                pattern: ^@-?[0-9]+$
                type: string
            Idempotent-Replayed:
              description: True when this response was replayed from an earlier attempt.
              schema:
                type: boolean
            Link:
              description: |-
                Links related to lifecycle or remediation documentation.

                Optional related resources.
              schema:
                type: string
            RateLimit:
              description: |-
                Current rate-limit state.

                Optional rate limit information.
              schema:
                type: string
            RateLimit-Policy:
              description: |-
                Rate-limit policy applied by the gateway.

                Optional rate limit policy.
              schema:
                type: string
            Retry-After:
              description: |-
                Delay before retrying, in seconds or as an HTTP date.

                Optional retry delay or HTTP date.
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594 HTTP-date (IMF-fixdate) after which the operation may
                become unavailable, for example `Thu, 31 Dec 2026 23:59:59 GMT`.
              schema:
                pattern: >-
                  ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]{2}
                  (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{4}
                  [0-9]{2}:[0-9]{2}:[0-9]{2} GMT$
                type: string
            X-Request-ID:
              description: |-
                Identifier for this HTTP attempt.

                Application request identifier.
              schema:
                type: string
            X-Trace-ID:
              description: >-
                Trace ID of this request. Sent alongside X-Request-ID when a
                middleware published a trace ID for the request.
              schema:
                pattern: ^(?!0{32}$)[0-9a-f]{32}$
                type: string
        '502':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/UpstreamFailureProblem'
          description: 'UPSTREAM_FAILURE: Upstream Service Failure'
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
        '503':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/UpstreamUnavailableProblem'
          description: 'UPSTREAM_UNAVAILABLE: Upstream Service Unavailable'
          headers:
            Deprecation:
              description: >-
                RFC 9745 structured-field Date at which the operation was or
                will be deprecated: `@` followed by Unix seconds, for example
                `@1767225599`.
              schema:
                pattern: ^@-?[0-9]+$
                type: string
            Idempotent-Replayed:
              description: True when this response was replayed from an earlier attempt.
              schema:
                type: boolean
            Link:
              description: |-
                Links related to lifecycle or remediation documentation.

                Optional related resources.
              schema:
                type: string
            RateLimit:
              description: |-
                Current rate-limit state.

                Optional rate limit information.
              schema:
                type: string
            RateLimit-Policy:
              description: |-
                Rate-limit policy applied by the gateway.

                Optional rate limit policy.
              schema:
                type: string
            Retry-After:
              description: |-
                Delay before retrying, in seconds or as an HTTP date.

                Optional retry delay or HTTP date.
              schema:
                type: string
            Sunset:
              description: >-
                RFC 8594 HTTP-date (IMF-fixdate) after which the operation may
                become unavailable, for example `Thu, 31 Dec 2026 23:59:59 GMT`.
              schema:
                pattern: >-
                  ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]{2}
                  (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{4}
                  [0-9]{2}:[0-9]{2}:[0-9]{2} GMT$
                type: string
            X-Request-ID:
              description: |-
                Identifier for this HTTP attempt.

                Application request identifier.
              schema:
                type: string
            X-Trace-ID:
              description: >-
                Trace ID of this request. Sent alongside X-Request-ID when a
                middleware published a trace ID for the request.
              schema:
                pattern: ^(?!0{32}$)[0-9a-f]{32}$
                type: string
        '504':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/GetEffectiveTermsGatewayTimeoutProblem'
          description: >-
            REQUEST_TIMEOUT: Request Timeout; UPSTREAM_TIMEOUT: Upstream Service
            Timeout
          headers:
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Sunset:
              $ref: '#/components/headers/Sunset'
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
            X-Trace-ID:
              $ref: '#/components/headers/X-Trace-ID'
      security:
        - accountServiceKey: []
        - serviceIdentityBearer: []
        - oauth2:
            - billing:read
components:
  schemas:
    GetEffectiveTermsResponse:
      additionalProperties: false
      properties:
        creditBalance:
          anyOf:
            - $ref: '#/components/schemas/CreditBalance'
            - type: 'null'
          description: >-
            Credit the paying organization holds on credit notes, such as the
            unused time of a plan an upgrade replaced. It offsets that
            organization's next invoices of any kind except one-off invoices.
            Prepaid wallet credit is separate. Null when it holds none.
        subscriptions:
          description: >-
            One entry per category the project holds, by category. Empty means
            it holds none.
          items:
            $ref: '#/components/schemas/SubscriptionTerms'
          type: array
        timeZone:
          description: >-
            The IANA time zone the payer is billed in, e.g. America/Los_Angeles.
            Billing periods start and end at its midnights, so read their
            calendar dates in it.
          type: string
      required:
        - creditBalance
        - subscriptions
        - timeZone
      type: object
    InvalidArgumentProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: INVALID_ARGUMENT
        status: 400
        title: Invalid Argument
        type: https://photon.codes/docs/problems/invalid-argument
      properties:
        code:
          const: INVALID_ARGUMENT
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 400
          type: number
        title:
          const: Invalid Argument
          type: string
        type:
          const: https://photon.codes/docs/problems/invalid-argument
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    NotAuthenticatedProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: NOT_AUTHENTICATED
        status: 401
        title: Not Authenticated
        type: https://photon.codes/docs/problems/not-authenticated
      properties:
        code:
          const: NOT_AUTHENTICATED
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 401
          type: number
        title:
          const: Not Authenticated
          type: string
        type:
          const: https://photon.codes/docs/problems/not-authenticated
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    GetEffectiveTermsForbiddenProblem:
      oneOf:
        - $ref: '#/components/schemas/ForbiddenProblem'
        - $ref: '#/components/schemas/InsufficientScopeProblem'
        - $ref: '#/components/schemas/OrganizationSsoRequiredProblem'
        - $ref: '#/components/schemas/ResourceMismatchProblem'
    FailedPreconditionProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: FAILED_PRECONDITION
        status: 409
        title: Failed Precondition
        type: https://photon.codes/docs/problems/failed-precondition
      properties:
        code:
          const: FAILED_PRECONDITION
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 409
          type: number
        title:
          const: Failed Precondition
          type: string
        type:
          const: https://photon.codes/docs/problems/failed-precondition
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    ValidationFailedProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: VALIDATION_FAILED
        issues:
          - code: invalid_type
            location: json
            message: Expected a string.
            path: /name
        status: 422
        title: Request Validation Failed
        type: https://photon.codes/docs/problems/validation-failed
      properties:
        code:
          const: VALIDATION_FAILED
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        issues:
          items:
            $ref: '#/components/schemas/ValidationIssue'
          type: array
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 422
          type: number
        title:
          const: Request Validation Failed
          type: string
        type:
          const: https://photon.codes/docs/problems/validation-failed
          type: string
      required:
        - issues
        - code
        - status
        - title
        - type
      type: object
    GetEffectiveTermsInternalServerErrorProblem:
      oneOf:
        - $ref: '#/components/schemas/InternalErrorProblem'
        - $ref: '#/components/schemas/InvalidAuthContextProblem'
    UpstreamFailureProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: UPSTREAM_FAILURE
        status: 502
        title: Upstream Service Failure
        type: https://photon.codes/docs/problems/upstream-failure
      properties:
        code:
          const: UPSTREAM_FAILURE
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 502
          type: number
        title:
          const: Upstream Service Failure
          type: string
        type:
          const: https://photon.codes/docs/problems/upstream-failure
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    UpstreamUnavailableProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: UPSTREAM_UNAVAILABLE
        status: 503
        title: Upstream Service Unavailable
        type: https://photon.codes/docs/problems/upstream-unavailable
      properties:
        code:
          const: UPSTREAM_UNAVAILABLE
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 503
          type: number
        title:
          const: Upstream Service Unavailable
          type: string
        type:
          const: https://photon.codes/docs/problems/upstream-unavailable
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    GetEffectiveTermsGatewayTimeoutProblem:
      oneOf:
        - $ref: '#/components/schemas/RequestTimeoutProblem'
        - $ref: '#/components/schemas/UpstreamTimeoutProblem'
    CreditBalance:
      additionalProperties: false
      properties:
        balanceCents:
          description: Credit left to offset the next invoices, in cents.
          exclusiveMinimum: 0
          maximum: 9007199254740991
          type: integer
        currency:
          description: ISO currency code.
          type: string
      required:
        - balanceCents
        - currency
      type: object
    SubscriptionTerms:
      additionalProperties: false
      description: >-
        What one subscription is billed on now. plan is the plan as this
        subscription has it: its own prices when overridden, each fixed charge
        at the subscription's price and quantity, and entitlements resolved with
        overrides.
      properties:
        cancelsAt:
          anyOf:
            - description: ISO 8601.
              type: string
            - type: 'null'
          description: When the subscription ends instead of renewing, ISO 8601.
        category:
          description: Category slug, e.g. analytics or messaging.
          pattern: ^[a-z][a-z0-9_]{0,63}$
          type: string
        currentPeriodEnd:
          description: ISO 8601.
          type: string
        currentPeriodStart:
          description: ISO 8601.
          type: string
        nextBillingAt:
          description: >-
            When the next invoice is issued: the second after the period ends,
            ISO 8601.
          type: string
        paymentMode:
          $ref: '#/components/schemas/PaymentMode'
        plan:
          $ref: '#/components/schemas/BillingPlan'
        planSource:
          $ref: '#/components/schemas/PlanSource'
        scheduledPlanChange:
          anyOf:
            - $ref: '#/components/schemas/ScheduledPlanChange'
            - type: 'null'
          description: A downgrade waiting for the period end, or null.
      required:
        - cancelsAt
        - category
        - currentPeriodEnd
        - currentPeriodStart
        - nextBillingAt
        - paymentMode
        - plan
        - planSource
        - scheduledPlanChange
      type: object
    JsonValue:
      anyOf:
        - type: string
        - type: number
        - type: boolean
        - type: 'null'
        - items:
            $ref: '#/components/schemas/JsonValue'
          type: array
        - additionalProperties:
            $ref: '#/components/schemas/JsonValue'
          propertyNames:
            type: string
          type: object
    ForbiddenProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: FORBIDDEN
        status: 403
        title: Forbidden
        type: https://photon.codes/docs/problems/forbidden
      properties:
        code:
          const: FORBIDDEN
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 403
          type: number
        title:
          const: Forbidden
          type: string
        type:
          const: https://photon.codes/docs/problems/forbidden
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    InsufficientScopeProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: INSUFFICIENT_SCOPE
        status: 403
        title: Insufficient Scope
        type: https://photon.codes/docs/problems/insufficient-scope
      properties:
        code:
          const: INSUFFICIENT_SCOPE
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 403
          type: number
        title:
          const: Insufficient Scope
          type: string
        type:
          const: https://photon.codes/docs/problems/insufficient-scope
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    OrganizationSsoRequiredProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: ORGANIZATION_SSO_REQUIRED
        status: 403
        title: Organization SSO Required
        type: https://photon.codes/docs/problems/organization-sso-required
      properties:
        code:
          const: ORGANIZATION_SSO_REQUIRED
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 403
          type: number
        title:
          const: Organization SSO Required
          type: string
        type:
          const: https://photon.codes/docs/problems/organization-sso-required
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    ResourceMismatchProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: RESOURCE_MISMATCH
        status: 403
        title: Resource Mismatch
        type: https://photon.codes/docs/problems/resource-mismatch
      properties:
        code:
          const: RESOURCE_MISMATCH
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 403
          type: number
        title:
          const: Resource Mismatch
          type: string
        type:
          const: https://photon.codes/docs/problems/resource-mismatch
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    ValidationIssue:
      additionalProperties: false
      properties:
        code:
          minLength: 1
          type: string
        location:
          $ref: '#/components/schemas/ValidationLocation'
        message:
          minLength: 1
          type: string
        path:
          type: string
      required:
        - code
        - location
        - message
        - path
      type: object
    InternalErrorProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: INTERNAL_ERROR
        status: 500
        title: Internal Server Error
        type: https://photon.codes/docs/problems/internal-error
      properties:
        code:
          const: INTERNAL_ERROR
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 500
          type: number
        title:
          const: Internal Server Error
          type: string
        type:
          const: https://photon.codes/docs/problems/internal-error
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    InvalidAuthContextProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: INVALID_AUTH_CONTEXT
        status: 500
        title: Invalid Authentication Context
        type: https://photon.codes/docs/problems/invalid-auth-context
      properties:
        code:
          const: INVALID_AUTH_CONTEXT
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 500
          type: number
        title:
          const: Invalid Authentication Context
          type: string
        type:
          const: https://photon.codes/docs/problems/invalid-auth-context
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    RequestTimeoutProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: REQUEST_TIMEOUT
        status: 504
        title: Request Timeout
        type: https://photon.codes/docs/problems/request-timeout
      properties:
        code:
          const: REQUEST_TIMEOUT
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 504
          type: number
        title:
          const: Request Timeout
          type: string
        type:
          const: https://photon.codes/docs/problems/request-timeout
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    UpstreamTimeoutProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: UPSTREAM_TIMEOUT
        status: 504
        title: Upstream Service Timeout
        type: https://photon.codes/docs/problems/upstream-timeout
      properties:
        code:
          const: UPSTREAM_TIMEOUT
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 504
          type: number
        title:
          const: Upstream Service Timeout
          type: string
        type:
          const: https://photon.codes/docs/problems/upstream-timeout
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    PaymentMode:
      enum:
        - automatic
        - manual
      type: string
      x-enumDescriptions:
        automatic: Charged to the payer's payment method when issued.
        manual: Paid outside the payment provider.
    BillingPlan:
      additionalProperties: false
      properties:
        baseAmountCents:
          description: Recurring base price in whole cents.
          maximum: 9007199254740991
          minimum: 0
          type: integer
        categoryDisplayName:
          anyOf:
            - maxLength: 255
              minLength: 1
              type: string
            - type: 'null'
          description: >-
            Display name for the subscription category; absent or null when
            unconfigured.
        currency:
          description: ISO currency code.
          type: string
        description:
          anyOf:
            - type: string
            - type: 'null'
        entitlements:
          items:
            $ref: '#/components/schemas/BillingPlanEntitlement'
          type: array
        fixedCharges:
          items:
            $ref: '#/components/schemas/FixedCharge'
          type: array
        interval:
          $ref: '#/components/schemas/BillingPlanInterval'
        isDefault:
          description: >-
            The category's default plan: the one a project holds when it pays
            for none, and moves to at the period end when it leaves a paid plan.
            At most one per category.
          type: boolean
        minimumCommitment:
          anyOf:
            - $ref: '#/components/schemas/BillingPlanMinimumCommitment'
            - type: 'null'
        name:
          type: string
        payInAdvance:
          type: boolean
        planCode:
          maxLength: 64
          minLength: 1
          type: string
        tier:
          anyOf:
            - maximum: 9007199254740991
              minimum: -9007199254740991
              type: integer
            - type: 'null'
          description: >-
            Rank within the category: moving to a higher tier is an upgrade and
            applies now, to a lower one a downgrade scheduled for the period
            end. Null when the plan has none.
        tierDisplayName:
          anyOf:
            - maxLength: 255
              minLength: 1
              type: string
            - type: 'null'
          description: >-
            The plan's tier as customers see it, e.g. Pro for Messaging Pro,
            where the category is already clear. Null when unconfigured.
        usageCharges:
          items:
            $ref: '#/components/schemas/UsageCharge'
          type: array
        usageThresholds:
          description: Progressive-billing thresholds, ordered by amount.
          items:
            $ref: '#/components/schemas/BillingPlanUsageThreshold'
          type: array
      required:
        - baseAmountCents
        - currency
        - description
        - entitlements
        - fixedCharges
        - interval
        - isDefault
        - minimumCommitment
        - name
        - payInAdvance
        - planCode
        - tier
        - tierDisplayName
        - usageCharges
        - usageThresholds
      type: object
    PlanSource:
      enum:
        - catalog
        - override
      type: string
      x-enumDescriptions:
        catalog: A plan published in the catalog, unchanged.
        override: >-
          Terms of its own: a plan override on the subscription, or a plan
          outside the published catalog.
    ScheduledPlanChange:
      additionalProperties: false
      properties:
        effectiveAt:
          description: ISO 8601.
          type: string
        planCode:
          maxLength: 64
          minLength: 1
          type: string
      required:
        - effectiveAt
        - planCode
      type: object
    ValidationLocation:
      enum:
        - body
        - cookie
        - form
        - header
        - json
        - param
        - query
      type: string
    BillingPlanEntitlement:
      additionalProperties: false
      properties:
        featureKey:
          type: string
        value:
          type: string
      required:
        - featureKey
        - value
      type: object
    FixedCharge:
      additionalProperties: false
      properties:
        chargeModel:
          $ref: '#/components/schemas/FixedChargeModel'
        displayName:
          type: string
        fixedChargeCode:
          type: string
        payInAdvance:
          type: boolean
        pricing:
          $ref: '#/components/schemas/FixedChargePricing'
        prorated:
          type: boolean
        quantity:
          maximum: 9007199254740991
          minimum: 0
          type: integer
      required:
        - chargeModel
        - displayName
        - fixedChargeCode
        - payInAdvance
        - pricing
        - prorated
        - quantity
      type: object
    BillingPlanInterval:
      enum:
        - weekly
        - monthly
        - quarterly
        - semiannual
        - yearly
      type: string
    BillingPlanMinimumCommitment:
      additionalProperties: false
      description: >-
        When the plan's fees for an interval come to less than amountCents, the
        difference is invoiced at the end of the period.
      properties:
        amountCents:
          description: Least the plan bills each interval, in whole cents.
          maximum: 9007199254740991
          minimum: 0
          type: integer
        displayName:
          anyOf:
            - type: string
            - type: 'null'
      required:
        - amountCents
        - displayName
      type: object
    UsageCharge:
      additionalProperties: false
      properties:
        chargeCode:
          anyOf:
            - type: string
            - type: 'null'
        chargeModel:
          $ref: '#/components/schemas/UsageChargeModel'
        displayName:
          anyOf:
            - type: string
            - type: 'null'
        filters:
          items:
            $ref: '#/components/schemas/UsageChargeFilter'
          type: array
        invoiceable:
          type: boolean
        metricCode:
          type: string
        minimumAmountCents:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        payInAdvance:
          type: boolean
        pricing:
          $ref: '#/components/schemas/UsageChargePricing'
        prorated:
          type: boolean
      required:
        - chargeCode
        - chargeModel
        - displayName
        - filters
        - invoiceable
        - metricCode
        - minimumAmountCents
        - payInAdvance
        - pricing
        - prorated
      type: object
    BillingPlanUsageThreshold:
      additionalProperties: false
      properties:
        amountCents:
          description: >-
            Usage amount, in whole cents, at which usage is invoiced before the
            period ends.
          maximum: 9007199254740991
          minimum: 0
          type: integer
        displayName:
          anyOf:
            - type: string
            - type: 'null'
        recurring:
          description: Whether usage is invoiced again every further amountCents.
          type: boolean
      required:
        - amountCents
        - displayName
        - recurring
      type: object
    FixedChargeModel:
      enum:
        - graduated
        - standard
        - volume
      type: string
    FixedChargePricing:
      additionalProperties: false
      properties:
        amount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        tiers:
          items:
            $ref: '#/components/schemas/FixedChargeTier'
          type: array
      required:
        - amount
        - tiers
      type: object
    UsageChargeModel:
      enum:
        - dynamic
        - graduated
        - graduated_percentage
        - package
        - percentage
        - standard
        - volume
      type: string
    UsageChargeFilter:
      additionalProperties: false
      properties:
        displayName:
          anyOf:
            - type: string
            - type: 'null'
        pricing:
          $ref: '#/components/schemas/UsageChargePricing'
        values:
          items:
            $ref: '#/components/schemas/UsageChargeFilterValue'
          type: array
      required:
        - displayName
        - pricing
        - values
      type: object
    UsageChargePricing:
      additionalProperties: false
      properties:
        amount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        fixedAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        freeUnits:
          anyOf:
            - maximum: 9007199254740991
              minimum: 0
              type: integer
            - type: 'null'
        freeUnitsPerEvents:
          anyOf:
            - maximum: 9007199254740991
              minimum: 0
              type: integer
            - type: 'null'
        freeUnitsPerTotalAggregation:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        packageSize:
          anyOf:
            - maximum: 9007199254740991
              minimum: 0
              type: integer
            - type: 'null'
        perTransactionMaxAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        perTransactionMinAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        pricingGroupKeys:
          items:
            type: string
          type: array
        rate:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        tiers:
          items:
            $ref: '#/components/schemas/UsageChargeTier'
          type: array
      required:
        - amount
        - fixedAmount
        - freeUnits
        - freeUnitsPerEvents
        - freeUnitsPerTotalAggregation
        - packageSize
        - perTransactionMaxAmount
        - perTransactionMinAmount
        - pricingGroupKeys
        - rate
        - tiers
      type: object
    FixedChargeTier:
      additionalProperties: false
      properties:
        flatAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        fromUnit:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        perUnitAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        toUnit:
          anyOf:
            - maximum: 9007199254740991
              minimum: 0
              type: integer
            - type: 'null'
      required:
        - flatAmount
        - fromUnit
        - perUnitAmount
        - toUnit
      type: object
    UsageChargeFilterValue:
      additionalProperties: false
      properties:
        key:
          type: string
        values:
          items:
            type: string
          type: array
      required:
        - key
        - values
      type: object
    UsageChargeTier:
      additionalProperties: false
      properties:
        flatAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        fromUnit:
          maximum: 9007199254740991
          minimum: 0
          type: integer
        perUnitAmount:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        rate:
          anyOf:
            - description: >-
                Decimal amount in the plan currency. Kept as text so sub-cent
                unit prices remain exact.
              pattern: ^\d+(?:\.\d+)?$
              type: string
            - type: 'null'
        toUnit:
          anyOf:
            - maximum: 9007199254740991
              minimum: 0
              type: integer
            - type: 'null'
      required:
        - flatAmount
        - fromUnit
        - perUnitAmount
        - rate
        - toUnit
      type: object
  headers:
    Deprecation:
      description: >-
        RFC 9745 structured-field Date at which the operation was or will be
        deprecated: `@` followed by Unix seconds, for example `@1767225599`.
      schema:
        pattern: ^@-?[0-9]+$
        type: string
    Idempotent-Replayed:
      description: True when this response was replayed from an earlier attempt.
      schema:
        type: boolean
    Link:
      description: Links related to lifecycle or remediation documentation.
      schema:
        type: string
    RateLimit:
      description: Current rate-limit state.
      schema:
        type: string
    RateLimit-Policy:
      description: Rate-limit policy applied by the gateway.
      schema:
        type: string
    Retry-After:
      description: Delay before retrying, in seconds or as an HTTP date.
      schema:
        type: string
    Sunset:
      description: >-
        RFC 8594 HTTP-date (IMF-fixdate) after which the operation may become
        unavailable, for example `Thu, 31 Dec 2026 23:59:59 GMT`.
      schema:
        pattern: >-
          ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-9]{2}
          (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{4}
          [0-9]{2}:[0-9]{2}:[0-9]{2} GMT$
        type: string
    X-Request-ID:
      description: Identifier for this HTTP attempt.
      schema:
        type: string
    X-Trace-ID:
      description: >-
        Trace ID of this request. Sent alongside X-Request-ID when a middleware
        published a trace ID for the request.
      schema:
        pattern: ^(?!0{32}$)[0-9a-f]{32}$
        type: string
  securitySchemes:
    accountServiceKey:
      description: >-
        Account Service Key, prefixed with `pho_ask_`, sent as `Authorization:
        Bearer <key>`. Acts on behalf of its owning account, subject to the
        permissions and credential restrictions of each operation. Account
        access tokens and OAuth grants also use the Bearer header. In
        organizations that require SSO, Account Service Keys are not accepted
        for managing the organization's SSO settings, deleting the organization,
        or checking whether it can be deleted.
      scheme: bearer
      type: http
    serviceIdentityBearer:
      description: >-
        Organization Service Identity API key or M2M access token, sent as
        `Authorization: Bearer <credential>`. Restricted to its organization and
        explicitly granted business permissions. It does not authorize human
        organization governance or Photon credential management. Never send an
        M2M client secret to a business endpoint.
      scheme: bearer
      type: http
    oauth2:
      description: >-
        OAuth grant issued by the Photon authorization server. The token is a
        bearer JWT whose consented scope is intersected with the permissions the
        route grants; an empty intersection is `403 insufficient_scope`.
      flows:
        authorizationCode:
          authorizationUrl: https://auth.photon.codes/oauth2/authorize
          scopes:
            account:create_project: Create a project owned by the account.
            account:read: View account profile.
            account:read_projects: >-
              List projects associated with the account; does not grant access
              to project contents.
            account:write: Update account name and profile.
            billing:read: View invoices, usage, payment status.
            events:read: >-
              Query stored Events and discover their SQL schema within a
              project.
            organization:create_project: Create a project in the organization.
            organization:read: View organization name and avatar.
            organization:read_projects: List projects in the organization.
            platforms:read: View project platform configuration.
            platforms:write: Change project platform configuration.
            project:delete: Permanently delete the project.
            project:read: View non-sensitive project settings.
            project:read_usage: View project usage and costs.
            project:write: >-
              Change agent profiles, webhook settings, and other project
              configuration.
            ten_dlc:read: View organization 10DLC Brand and Campaign registration records.
            ten_dlc:write: >-
              Register and update organization 10DLC Brands and Campaigns,
              including OTP operations.
          tokenUrl: https://auth.photon.codes/oauth2/token
      type: oauth2

````

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