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

# Create or get a Space

> Creates or returns a project Space. Idempotency-Key is required for every platform and binds the project, platform and initial User IDs (unordered except the iMessage creator in first position) for 24 hours after workflow completion. Concurrent matching requests join the same operation; conflicting reuse returns 422 once its outcome is available. A new email key creates a new thread; direct Spaces and SMS groups converge by participants. Every creation and successful replay requires at least one currently project-owned Agent, or for iMessage a shared-line Agent in a direct Space whose peer has an active Assignment of this project on that line. For iMessage, an existing exact match is reused; otherwise the first participant must be a project-owned dedicated phone Agent and creates the native direct chat or group. Multiple matching native groups return SPACE_AMBIGUOUS; incomplete group membership cannot establish an exact match. Replays return 200 and the current stored Space, with Idempotent-Replayed: true. A timeout does not cancel accepted work: retry the same key and input.



## OpenAPI

````yaml https://api.photon.codes/openapi.json post /v1/projects/{id}/spaces
openapi: 3.1.0
info:
  title: Photon API
  version: 1.0.0
servers:
  - url: https://api.photon.codes
security: []
paths:
  /v1/projects/{id}/spaces:
    post:
      tags:
        - Spaces
      summary: Create or get a Space
      description: >-
        Creates or returns a project Space. Idempotency-Key is required for
        every platform and binds the project, platform and initial User IDs
        (unordered except the iMessage creator in first position) for 24 hours
        after workflow completion. Concurrent matching requests join the same
        operation; conflicting reuse returns 422 once its outcome is available.
        A new email key creates a new thread; direct Spaces and SMS groups
        converge by participants. Every creation and successful replay requires
        at least one currently project-owned Agent, or for iMessage a
        shared-line Agent in a direct Space whose peer has an active Assignment
        of this project on that line. For iMessage, an existing exact match is
        reused; otherwise the first participant must be a project-owned
        dedicated phone Agent and creates the native direct chat or group.
        Multiple matching native groups return SPACE_AMBIGUOUS; incomplete group
        membership cannot establish an exact match. Replays return 200 and the
        current stored Space, with Idempotent-Replayed: true. A timeout does not
        cancel accepted work: retry the same key and input.
      operationId: createOrGetSpace
      parameters:
        - in: path
          name: id
          required: true
          schema:
            pattern: ^pho_prj_[0-7][0-9a-hjkmnp-tv-z]{25}$
            type: string
        - description: >-
            Required for every platform; 1-255 visible ASCII characters. Reuse
            for retries. For email, the same key and initial participants
            retrieve the same Space, and a new key starts a separate
            conversation. SMS identifies its Space by participants, even with a
            new key. iMessage binds the key to the first participant as creator
            and the remaining unordered User IDs. Existing matching Spaces are
            reused.
          in: header
          name: idempotency-key
          required: true
          schema:
            maxLength: 255
            minLength: 1
            pattern: ^[\x21-\x7e]+$
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrGetSpaceRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformSpace'
          description: >-
            The Space already existed and is returned in its authoritative
            stored state.
          headers:
            Cache-Control:
              description: Prevents storage of this create-or-get response.
              schema:
                type: string
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              description: True when joining or replaying an accepted operation.
              schema:
                type: string
            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'
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformSpace'
          description: The Space was created.
          headers:
            Cache-Control:
              description: Prevents storage of this create-or-get response.
              schema:
                type: string
            Deprecation:
              $ref: '#/components/headers/Deprecation'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Link:
              $ref: '#/components/headers/Link'
            Location:
              description: Canonical URL of the newly created Space.
              schema:
                format: uri-reference
                type: string
            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/CreateOrGetSpaceBadRequestProblem'
          description: >-
            HTTP_ERROR: Request Failed; INVALID_REQUEST: Invalid Request;
            IDEMPOTENCY_KEY_REQUIRED: Idempotency Key Required;
            IDEMPOTENCY_KEY_INVALID: Idempotency Key Invalid
          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/CreateOrGetSpaceForbiddenProblem'
          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
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/UserNotFoundProblem'
          description: 'USER_NOT_FOUND: User Not Found'
          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'
        '409':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/SpaceAmbiguousProblem'
          description: 'SPACE_AMBIGUOUS: Multiple Matching Spaces'
          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'
        '413':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PayloadTooLargeProblem'
          description: 'PAYLOAD_TOO_LARGE: Payload Too Large'
          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/CreateOrGetSpaceUnprocessableEntityProblem
          description: >-
            SPACE_REQUIRES_OWNED_AGENT: Space Requires Owned Agent;
            IDEMPOTENCY_KEY_REUSED: Idempotency Key Reused;
            OPERATION_UNAVAILABLE: Operation Unavailable; 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/CreateOrGetSpaceInternalServerErrorProblem
          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/CreateOrGetSpaceServiceUnavailableProblem'
          description: >-
            IDEMPOTENCY_UNAVAILABLE: Idempotency Unavailable;
            UPSTREAM_UNAVAILABLE: Upstream Service Unavailable


            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/CreateOrGetSpaceGatewayTimeoutProblem'
          description: >-
            UPSTREAM_TIMEOUT: Upstream Service Timeout; REQUEST_TIMEOUT: Request
            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: []
        - projectApiKey: []
        - oauth2:
            - project:write
components:
  schemas:
    CreateOrGetSpaceRequest:
      additionalProperties: false
      properties:
        participantIds:
          description: >-
            Canonical Photon User IDs from this project and platform. iMessage
            uses the first participant as creator when a new chat is needed;
            remaining order is ignored. Other platforms ignore all participant
            order. Counts: iMessage 2-1000; both WhatsApp platforms exactly 2;
            email 1-51; SMS 2-9. Every Space requires a currently project-owned
            Agent.
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          $ref: '#/components/schemas/Platform'
      required:
        - participantIds
        - platform
      type: object
    PlatformSpace:
      allOf:
        - $ref: '#/components/schemas/Space'
        - $ref: '#/components/schemas/SupportedPlatformConstraint'
      example:
        createdAt: '2026-01-01T00:00:00.000Z'
        details: {}
        id: pho_spc_00000000000000000000000001
        kind: direct
        metadata: {}
        participantIds:
          - pho_usr_00000000000000000000000001
          - pho_usr_00000000000000000000000002
        platform: whatsapp
        projectId: pho_prj_00000000000000000000000001
        updatedAt: '2026-01-01T00:00:00.000Z'
    CreateOrGetSpaceBadRequestProblem:
      oneOf:
        - $ref: '#/components/schemas/HttpErrorProblem'
        - $ref: '#/components/schemas/InvalidRequestProblem'
        - $ref: '#/components/schemas/IdempotencyKeyRequiredProblem'
        - $ref: '#/components/schemas/IdempotencyKeyInvalidProblem'
    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
    CreateOrGetSpaceForbiddenProblem:
      oneOf:
        - $ref: '#/components/schemas/ForbiddenProblem'
        - $ref: '#/components/schemas/InsufficientScopeProblem'
        - $ref: '#/components/schemas/OrganizationSsoRequiredProblem'
        - $ref: '#/components/schemas/ResourceMismatchProblem'
    UserNotFoundProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: USER_NOT_FOUND
        status: 404
        title: User Not Found
        type: https://photon.codes/docs/problems/user-not-found
      properties:
        code:
          const: USER_NOT_FOUND
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 404
          type: number
        title:
          const: User Not Found
          type: string
        type:
          const: https://photon.codes/docs/problems/user-not-found
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    SpaceAmbiguousProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: SPACE_AMBIGUOUS
        status: 409
        title: Multiple Matching Spaces
        type: https://photon.codes/docs/problems/space-ambiguous
      properties:
        code:
          const: SPACE_AMBIGUOUS
          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: Multiple Matching Spaces
          type: string
        type:
          const: https://photon.codes/docs/problems/space-ambiguous
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    PayloadTooLargeProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: PAYLOAD_TOO_LARGE
        status: 413
        title: Payload Too Large
        type: https://photon.codes/docs/problems/payload-too-large
      properties:
        code:
          const: PAYLOAD_TOO_LARGE
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 413
          type: number
        title:
          const: Payload Too Large
          type: string
        type:
          const: https://photon.codes/docs/problems/payload-too-large
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    CreateOrGetSpaceUnprocessableEntityProblem:
      oneOf:
        - $ref: '#/components/schemas/SpaceRequiresOwnedAgentProblem'
        - $ref: '#/components/schemas/IdempotencyKeyReusedProblem'
        - $ref: '#/components/schemas/OperationUnavailableProblem'
        - $ref: '#/components/schemas/ValidationFailedProblem'
    CreateOrGetSpaceInternalServerErrorProblem:
      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
    CreateOrGetSpaceServiceUnavailableProblem:
      oneOf:
        - $ref: '#/components/schemas/IdempotencyUnavailableProblem'
        - $ref: '#/components/schemas/UpstreamUnavailableProblem'
    CreateOrGetSpaceGatewayTimeoutProblem:
      oneOf:
        - $ref: '#/components/schemas/UpstreamTimeoutProblem'
        - $ref: '#/components/schemas/RequestTimeoutProblem'
    UserId:
      pattern: ^pho_usr_[0-7][0-9a-hjkmnp-tv-z]{25}$
      type: string
    Platform:
      enum:
        - sms
        - email
        - whatsapp
        - whatsapp_business
        - imessage
        - telegram
      type: string
    Space:
      anyOf:
        - $ref: '#/components/schemas/SmsSpace'
        - $ref: '#/components/schemas/WhatsappSpace'
        - $ref: '#/components/schemas/WhatsappBusinessSpace'
        - $ref: '#/components/schemas/EmailSpace'
        - $ref: '#/components/schemas/VoiceSpace'
        - $ref: '#/components/schemas/ImessageSpace'
        - $ref: '#/components/schemas/TelegramSpace'
      x-photon-extension:
        discriminator: platform
        fallback: '#/$defs/UnknownSpace'
        reserved:
          - sms
          - whatsapp
          - whatsapp_business
          - email
          - voice
          - imessage
          - telegram
    SupportedPlatformConstraint:
      additionalProperties: true
      properties:
        platform:
          $ref: '#/components/schemas/Platform'
      required:
        - platform
      type: object
    HttpErrorProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: HTTP_ERROR
        status: 400
        title: Request Failed
        type: https://photon.codes/docs/problems/http-error
      properties:
        code:
          const: HTTP_ERROR
          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: Request Failed
          type: string
        type:
          const: https://photon.codes/docs/problems/http-error
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    InvalidRequestProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: INVALID_REQUEST
        status: 400
        title: Invalid Request
        type: https://photon.codes/docs/problems/invalid-request
      properties:
        code:
          const: INVALID_REQUEST
          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 Request
          type: string
        type:
          const: https://photon.codes/docs/problems/invalid-request
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    IdempotencyKeyRequiredProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: IDEMPOTENCY_KEY_REQUIRED
        status: 400
        title: Idempotency Key Required
        type: https://photon.codes/docs/problems/idempotency-key-required
      properties:
        code:
          const: IDEMPOTENCY_KEY_REQUIRED
          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: Idempotency Key Required
          type: string
        type:
          const: https://photon.codes/docs/problems/idempotency-key-required
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    IdempotencyKeyInvalidProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: IDEMPOTENCY_KEY_INVALID
        status: 400
        title: Idempotency Key Invalid
        type: https://photon.codes/docs/problems/idempotency-key-invalid
      properties:
        code:
          const: IDEMPOTENCY_KEY_INVALID
          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: Idempotency Key Invalid
          type: string
        type:
          const: https://photon.codes/docs/problems/idempotency-key-invalid
          type: string
      required:
        - code
        - status
        - title
        - type
      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
    SpaceRequiresOwnedAgentProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: SPACE_REQUIRES_OWNED_AGENT
        status: 422
        title: Space Requires Owned Agent
        type: https://photon.codes/docs/problems/space-requires-owned-agent
      properties:
        code:
          const: SPACE_REQUIRES_OWNED_AGENT
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 422
          type: number
        title:
          const: Space Requires Owned Agent
          type: string
        type:
          const: https://photon.codes/docs/problems/space-requires-owned-agent
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    IdempotencyKeyReusedProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: IDEMPOTENCY_KEY_REUSED
        status: 422
        title: Idempotency Key Reused
        type: https://photon.codes/docs/problems/idempotency-key-reused
      properties:
        code:
          const: IDEMPOTENCY_KEY_REUSED
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 422
          type: number
        title:
          const: Idempotency Key Reused
          type: string
        type:
          const: https://photon.codes/docs/problems/idempotency-key-reused
          type: string
      required:
        - code
        - status
        - title
        - type
      type: object
    OperationUnavailableProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: OPERATION_UNAVAILABLE
        status: 422
        title: Operation Unavailable
        type: https://photon.codes/docs/problems/operation-unavailable
      properties:
        code:
          const: OPERATION_UNAVAILABLE
          type: string
        detail:
          minLength: 1
          type: string
        instance:
          minLength: 1
          type: string
        remediation:
          not: {}
        requestId:
          minLength: 1
          type: string
        status:
          const: 422
          type: number
        title:
          const: Operation Unavailable
          type: string
        type:
          const: https://photon.codes/docs/problems/operation-unavailable
          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
    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
    IdempotencyUnavailableProblem:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      example:
        code: IDEMPOTENCY_UNAVAILABLE
        status: 503
        title: Idempotency Unavailable
        type: https://photon.codes/docs/problems/idempotency-unavailable
      properties:
        code:
          const: IDEMPOTENCY_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: Idempotency Unavailable
          type: string
        type:
          const: https://photon.codes/docs/problems/idempotency-unavailable
          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
    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
    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
    SmsSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/SmsSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: sms
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    WhatsappSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/WhatsappSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: whatsapp
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    WhatsappBusinessSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/WhatsappBusinessSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: whatsapp_business
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    EmailSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/EmailSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: email
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    VoiceSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/VoiceSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: voice
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    ImessageSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/ImessageSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: imessage
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      type: object
    TelegramSpace:
      additionalProperties: false
      properties:
        createdAt:
          description: When Photon first persisted this resource.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        details:
          $ref: '#/components/schemas/TelegramSpaceDetails'
        id:
          $ref: '#/components/schemas/SpaceId'
        kind:
          minLength: 1
          type: string
        metadata:
          $ref: '#/components/schemas/ResourceMetadata'
        participantIds:
          items:
            $ref: '#/components/schemas/UserId'
          type: array
          uniqueItems: true
        platform:
          const: telegram
          type: string
        projectId:
          $ref: '#/components/schemas/ProjectId'
        updatedAt:
          description: When Photon last persisted a change to this resource's public state.
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
      required:
        - id
        - projectId
        - platform
        - kind
        - participantIds
        - details
        - metadata
        - createdAt
        - updatedAt
      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
    SmsSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    SpaceId:
      pattern: ^pho_spc_[0-7][0-9a-hjkmnp-tv-z]{25}$
      type: string
    ResourceMetadata:
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
      properties:
        displayName:
          minLength: 1
          type: string
        email:
          $ref: '#/components/schemas/EmailMetadata'
        spam:
          $ref: '#/components/schemas/SpamClassification'
      type: object
    ProjectId:
      pattern: ^pho_prj_[0-7][0-9a-hjkmnp-tv-z]{25}$
      type: string
    WhatsappSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    WhatsappBusinessSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    EmailSpaceDetails:
      additionalProperties: false
      properties:
        latestAddressing:
          $ref: '#/components/schemas/EmailAddressing'
          description: >-
            The latest eligible whole observation on a canonical Space, or this
            Message's immutable capture in an embedded Space. Absent when no
            observation is available.
      type: object
    VoiceSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    ImessageSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    TelegramSpaceDetails:
      additionalProperties: false
      properties: {}
      type: object
    ValidationLocation:
      enum:
        - body
        - cookie
        - form
        - header
        - json
        - param
        - query
      type: string
    EmailMetadata:
      additionalProperties: false
      properties:
        contentDisposition:
          $ref: '#/components/schemas/EmailContentDisposition'
        contentId:
          minLength: 1
          type: string
        originalHtml:
          type: string
        related:
          type: boolean
        sourceMediaType:
          minLength: 1
          type: string
        subject:
          type: string
      type: object
    SpamClassification:
      additionalProperties: false
      properties:
        classifiedAt:
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          type: string
        confidence:
          maximum: 1
          minimum: 0
          type: number
        source:
          minLength: 1
          type: string
        status:
          minLength: 1
          type: string
      required:
        - status
        - source
      type: object
    EmailAddressing:
      additionalProperties: false
      properties:
        bcc:
          description: >-
            Omitted means unavailable or undisclosed; an empty array means known
            empty. Never infer hidden recipients from another observation.
          items:
            $ref: '#/components/schemas/EmailMailbox'
          type: array
        cc:
          description: >-
            Omitted means unavailable or undisclosed; an empty array means known
            empty. Never infer hidden recipients from another observation.
          items:
            $ref: '#/components/schemas/EmailMailbox'
          type: array
        from:
          $ref: '#/components/schemas/EmailMailbox'
          description: >-
            The captured sender mailbox. Its address and resolved User ID must
            agree with the source Message's sentBy.
        replyTo:
          description: >-
            Omitted means unavailable or undisclosed; an empty array means known
            empty. Never infer hidden recipients from another observation.
          items:
            $ref: '#/components/schemas/EmailMailbox'
          type: array
        sourceMessageId:
          $ref: '#/components/schemas/MessageId'
          description: >-
            The Message that supplied this observation. In a Message Space
            snapshot this is the containing Message's own ID, not its parent ID.
        to:
          description: >-
            Omitted means unavailable or undisclosed; an empty array means known
            empty. Never infer hidden recipients from another observation.
          items:
            $ref: '#/components/schemas/EmailMailbox'
          type: array
      required:
        - sourceMessageId
        - from
      type: object
    EmailContentDisposition:
      enum:
        - inline
        - attachment
      type: string
    EmailMailbox:
      additionalProperties: false
      properties:
        address:
          $ref: '#/components/schemas/EmailMailboxAddress'
        name:
          description: The captured display name, when known.
          minLength: 1
          type: string
        userId:
          $ref: '#/components/schemas/UserId'
          description: >-
            The resolved Photon User ID, when available. Outbound admission must
            resolve every mailbox before capture.
      required:
        - address
      type: object
    MessageId:
      pattern: ^pho_msg_[0-7][0-9a-hjkmnp-tv-z]{25}$
      type: string
    EmailMailboxAddress:
      description: >-
        The captured mailbox address. Preserve local-part case; admission
        services own normalization and sending restrictions.
      minLength: 1
      oneOf:
        - type: string
        - pattern: '[\s\x00-\x1f\x7f]'
          type: string
      pattern: >-
        ^[^\s@\x00-\x1f\x7f]+@[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?)*$
      type: string
  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
    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
    Idempotent-Replayed:
      description: True when this response was replayed from an earlier attempt.
      schema:
        type: boolean
  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
    projectApiKey:
      description: >-
        Project API key, `pho_sk_` prefixed, sent as `Authorization: Bearer
        <key>`. Bound to one project, so it is accepted only under
        `/v1/projects/{projectId}` and refused everywhere else.
      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.