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

# Mint a presigned upload session

> Create-or-replace presigned upload (max 2 GiB). Complete with POST /document-uploads/{uploadId}/complete.

Requires the `documents:write` scope. Mutations require an `X-Idempotency-Key` header (responses are stored for replay; reusing a key with a different request returns 409 `IDEMPOTENCY_CONFLICT`). Requires `If-Match: "<revision>"`; a stale revision returns 409 `STALE_REVISION` and successful responses carry an `ETag`. Rate tier: `upload`.



## OpenAPI

````yaml /openapi.json post /api/v1/document-uploads
openapi: 3.1.0
info:
  title: Grand Charter Public API
  version: 1.0.0
  description: >-
    Org-scoped integration API for the Grand Charter legal platform.


    Authenticate every request with an integration API key in the `x-api-key`
    header. Keys are created in the attorney portal under **Settings →
    Integrations → API Credentials** (or by platform admins) and carry an
    explicit list of scopes; each operation below names its required scope
    (`x-required-scope`).


    Conventions: JSON bodies/responses in camelCase; money in integer cents;
    ISO-8601 UTC timestamps; keyset cursor pagination (`after`, `limit` →
    `nextCursor`); errors use `{ success: false, error, code }`.


    Idempotency: most mutations require an `X-Idempotency-Key` header — each
    operation description below says so explicitly. Exceptions that do NOT
    consume the header (retrying them can create duplicates): `POST /leads`,
    `PATCH /leads/{leadId}`, and `PATCH /cases/{caseId}`.
servers:
  - url: https://www.presolve.com
    description: Production
security:
  - integrationApiKey: []
tags:
  - name: Platform
  - name: Org & Team
  - name: Cases
  - name: Leads
  - name: Clients
  - name: Contacts
  - name: Documents
  - name: Notes
  - name: Tasks
  - name: Calendar
  - name: Deadlines
  - name: Intake
  - name: E-Sign
  - name: Billing
  - name: Settlement Funds
  - name: Referrals
  - name: Communications
  - name: Medical
  - name: Reports & Exports
  - name: Events & Webhooks
paths:
  /api/v1/document-uploads:
    post:
      tags:
        - Documents
      summary: Mint a presigned upload session
      description: >-
        Create-or-replace presigned upload (max 2 GiB). Complete with POST
        /document-uploads/{uploadId}/complete.


        Requires the `documents:write` scope. Mutations require an
        `X-Idempotency-Key` header (responses are stored for replay; reusing a
        key with a different request returns 409 `IDEMPOTENCY_CONFLICT`).
        Requires `If-Match: "<revision>"`; a stale revision returns 409
        `STALE_REVISION` and successful responses carry an `ETag`. Rate tier:
        `upload`.
      operationId: post_documentUploads
      parameters:
        - name: X-Idempotency-Key
          in: header
          required: true
          description: >-
            Stable caller-chosen key (max 200 chars) making the mutation safely
            retryable.
          schema:
            type: string
            maxLength: 200
        - name: If-Match
          in: header
          required: true
          description: Current entity revision, quoted (e.g. `"3"`), from the last ETag.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    operation:
                      type: string
                      const: create
                    caseId:
                      type: string
                      minLength: 1
                      maxLength: 200
                    folderId:
                      type:
                        - string
                        - 'null'
                      minLength: 1
                      maxLength: 200
                    name:
                      type: string
                      minLength: 1
                      maxLength: 255
                    mimeType:
                      type: string
                      minLength: 1
                      maxLength: 255
                    sizeBytes:
                      type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    sha256:
                      type: string
                      pattern: ^[A-Za-z0-9+/]{43}=$
                  required:
                    - operation
                    - caseId
                    - name
                    - mimeType
                    - sizeBytes
                    - sha256
                  additionalProperties: false
                - type: object
                  properties:
                    operation:
                      type: string
                      const: replace
                    documentId:
                      type: string
                      minLength: 1
                      maxLength: 200
                    mimeType:
                      type: string
                      minLength: 1
                      maxLength: 255
                    sizeBytes:
                      type: integer
                      minimum: -9007199254740991
                      maximum: 9007199254740991
                    sha256:
                      type: string
                      pattern: ^[A-Za-z0-9+/]{43}=$
                  required:
                    - operation
                    - documentId
                    - mimeType
                    - sizeBytes
                    - sha256
                  additionalProperties: false
      responses:
        '201':
          description: '{ success: true, upload: { id, url, ... } }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessEnvelope'
        '400':
          description: Validation failed (VALIDATION_FAILED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing, invalid, or expired API key (UNAUTHORIZED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: API key lacks the required scope (FORBIDDEN).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Resource not found in the caller’s organization (NOT_FOUND).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            Conflict: invalid state transition, duplicate entry, stale revision,
            or idempotency conflict.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded (RATE_LIMITED). Honor Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - integrationApiKey: []
components:
  schemas:
    SuccessEnvelope:
      type: object
      properties:
        success:
          type: boolean
          const: true
      required:
        - success
      additionalProperties: {}
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          const: false
        error:
          type: string
          description: >-
            Human-readable error message. 5xx responses are always scrubbed to
            "Internal server error".
        code:
          type: string
          description: >-
            Stable machine-readable error code (ErrorCode), e.g. UNAUTHORIZED,
            FORBIDDEN, VALIDATION_FAILED, NOT_FOUND, INVALID_STATE_TRANSITION,
            DUPLICATE_ENTRY, STALE_REVISION, IDEMPOTENCY_IN_PROGRESS,
            IDEMPOTENCY_CONFLICT, RATE_LIMITED, INTERNAL_ERROR.
      required:
        - success
        - error
        - code
  securitySchemes:
    integrationApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Org-issued integration API key (service account credential). The
        plaintext secret is shown once at creation.

````