Causa Prima Scribo API

The Scribo API from Causa Prima — 4 operation(s) for scribo.

OpenAPI Specification

causa-prima-scribo-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Invoice Invoices Scribo API
  version: 1.0.0
  description: Compliant e-invoice generation. **Phase 1 supports Germany (XRechnung / ZUGFeRD) and the United States (plain PDF) only** — any other sender jurisdiction is rejected with `unsupported_jurisdiction`. The `/api/v1/*` namespace served from `scribo.causaprima.ai` is the public surface — anonymous and rate-limited. The internal `/internal/scribo/*` namespace is used by the Causa Prima web app and MCP server and is not part of this contract.
  contact:
    name: Causa Prima
    url: https://causaprima.ai
servers:
- url: https://scribo.causaprima.ai
  description: Production
- url: http://localhost:3200
  description: Local development (scribo Next.js proxy)
tags:
- name: Scribo
paths:
  /api/v1/scribo/email-verifications:
    post:
      summary: Request a sender email-ownership challenge
      description: Emails a 6-character verification code (and magic link) to the address. Always returns a uniform 202 — new, returning, throttled, and send-failed callers are indistinguishable (anti-enumeration). Sends are rate-limited per email (resend cooldown + hourly cap).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestVerificationInput'
      responses:
        '202':
          description: Challenge accepted (uniform anti-enumeration shape)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationChallenge'
        '400':
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      tags:
      - Scribo
  /api/v1/scribo/email-verifications/{id}/redeem:
    post:
      summary: Redeem the emailed code for a verification token
      description: Exchanges the 6-character code for a verification_token, sent as X-Email-Verification-Token on POST /invoices. The token is reusable for ~30 minutes for the same sender email.
      parameters:
      - schema:
          type: string
          format: uuid
          description: Challenge UUID
        required: true
        name: id
        in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RedeemVerificationInput'
      responses:
        '200':
          description: Code accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationToken'
        '400':
          description: Wrong, expired, or revoked code — uniform verification_invalid across all three causes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      tags:
      - Scribo
  /api/v1/scribo/email-verifications/{id}:
    get:
      summary: Verification challenge status snapshot
      description: Polling fallback for browser flows waiting on the emailed magic link. verification_token is present only when status is `verified`.
      parameters:
      - schema:
          type: string
          format: uuid
          description: Challenge UUID
        required: true
        name: id
        in: path
      responses:
        '200':
          description: Challenge status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationSnapshot'
      tags:
      - Scribo
  /api/v1/scribo/email-verifications/{id}/events:
    get:
      summary: Verification challenge event stream
      description: Server-Sent Events stream of challenge status transitions; closes after `verified`. Browser flows use this instead of polling the snapshot endpoint.
      parameters:
      - schema:
          type: string
          format: uuid
          description: Challenge UUID
        required: true
        name: id
        in: path
      responses:
        '200':
          description: SSE stream
          content:
            text/event-stream:
              schema:
                type: string
      tags:
      - Scribo
components:
  schemas:
    VerificationToken:
      type: object
      properties:
        verification_token:
          type: string
        expires_at:
          type: string
          format: date-time
      required:
      - verification_token
      - expires_at
    VerificationSnapshot:
      oneOf:
      - type: object
        properties:
          status:
            type: string
            enum:
            - pending
          expires_at:
            type: string
        required:
        - status
        - expires_at
      - type: object
        properties:
          status:
            type: string
            enum:
            - verified
          verification_token:
            type: string
          expires_at:
            type: string
        required:
        - status
        - verification_token
        - expires_at
      - type: object
        properties:
          status:
            type: string
            enum:
            - expired
        required:
        - status
      - type: object
        properties:
          status:
            type: string
            enum:
            - revoked
        required:
        - status
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: invalid_input
            message:
              type: string
            details: {}
          required:
          - code
          - message
      required:
      - error
    RequestVerificationInput:
      type: object
      properties:
        email:
          type: string
          minLength: 3
          maxLength: 254
          format: email
      required:
      - email
      additionalProperties: false
    RedeemVerificationInput:
      type: object
      properties:
        code:
          type: string
          minLength: 1
          maxLength: 64
      required:
      - code
      additionalProperties: false
    VerificationChallenge:
      type: object
      properties:
        challenge_id:
          type: string
          format: uuid
        expires_at:
          type: string
          format: date-time
        next_request_allowed_at:
          type: string
          format: date-time
      required:
      - challenge_id
      - expires_at
      - next_request_allowed_at
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Optional API key for elevated quotas. Unauthenticated requests are accepted and rate-limited per IP.