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

# Create attachment upload

> Reserve one reusable image or PDF attachment (maximum 20 MB / 20,000,000 bytes). Supply its actual filename, MIME type, byte length and SHA-256. Send the original binary file with HTTP PUT to the returned signed URL and headers within 15 minutes; do not send ledger credentials to storage. Then call health_complete_attachment_upload. Files are not automatically transferred by MCP. Never invent a file or checksum.



## OpenAPI

````yaml /openapi.json post /v1/attachments/uploads
openapi: 3.1.1
info:
  title: Vitalog
  version: 1.0.1
  description: >-
    Single-user structured observations with equivalent REST and MCP domain
    services. Environment AUTH_KEY or revocable personal Bearer keys with
    required name, permissions and explicit expiry (including Never); Primary
    key management requires AUTH_KEY; the UI uses separate, root-verified
    30-minute management sessions. MCP clients use OAuth authorization code with
    S256 PKCE, issued after root sign-in. Clients are resolved through HTTPS
    metadata, pre-registration or dynamic registration. OAuth tokens grant MCP
    access only.
servers:
  - url: https://vitalog-api.example.com
    description: Production REST and MCP API
  - url: http://localhost:3000
    description: Loopback development; production requires TLS ingress
security: []
paths:
  /v1/attachments/uploads:
    post:
      tags:
        - Attachments
      summary: Create attachment upload
      description: >-
        Reserve one reusable image or PDF attachment (maximum 20 MB / 20,000,000
        bytes). Supply its actual filename, MIME type, byte length and SHA-256.
        Send the original binary file with HTTP PUT to the returned signed URL
        and headers within 15 minutes; do not send ledger credentials to
        storage. Then call health_complete_attachment_upload. Files are not
        automatically transferred by MCP. Never invent a file or checksum.
      operationId: health_create_attachment_upload
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 128
            pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $schema: https://json-schema.org/draft/2020-12/schema
              type: object
              properties:
                filename:
                  type: string
                  minLength: 1
                  maxLength: 200
                  pattern: ^[^/\\\x00-\x1f\x7f]+$
                content_type:
                  type: string
                  enum:
                    - application/pdf
                    - image/jpeg
                    - image/png
                    - image/webp
                    - image/gif
                    - image/avif
                    - image/heic
                    - image/heif
                    - image/tiff
                    - image/bmp
                byte_length:
                  type: integer
                  minimum: 1
                  maximum: 20000000
                sha256:
                  type: string
                  pattern: ^[0-9a-f]{64}$
              required:
                - filename
                - content_type
                - byte_length
                - sha256
              additionalProperties: false
      responses:
        '200':
          description: Committed mutation or durable idempotent replay
          content:
            application/json:
              schema:
                $schema: https://json-schema.org/draft/2020-12/schema
                type: object
                properties:
                  catalog_version:
                    type: string
                    const: 1.0.4
                  attachment:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                      filename:
                        type: string
                        minLength: 1
                        maxLength: 200
                        pattern: ^[^/\\\x00-\x1f\x7f]+$
                      content_type:
                        type: string
                        enum:
                          - application/pdf
                          - image/jpeg
                          - image/png
                          - image/webp
                          - image/gif
                          - image/avif
                          - image/heic
                          - image/heif
                          - image/tiff
                          - image/bmp
                      byte_length:
                        type: integer
                        minimum: 1
                        maximum: 20000000
                      sha256:
                        type: string
                        pattern: ^[0-9a-f]{64}$
                      status:
                        type: string
                        enum:
                          - pending
                          - ready
                          - expired
                      created_at:
                        $ref: '#/components/schemas/Schema_7e459b62f3fc___schema0'
                      upload_expires_at:
                        $ref: '#/components/schemas/Schema_7e459b62f3fc___schema0'
                      ready_at:
                        anyOf:
                          - $ref: '#/components/schemas/Schema_7e459b62f3fc___schema0'
                          - type: 'null'
                    required:
                      - id
                      - filename
                      - content_type
                      - byte_length
                      - sha256
                      - status
                      - created_at
                      - upload_expires_at
                      - ready_at
                    additionalProperties: false
                  upload:
                    anyOf:
                      - type: object
                        properties:
                          method:
                            type: string
                            const: PUT
                          url:
                            type: string
                            format: uri
                          headers:
                            type: object
                            properties:
                              Content-Type:
                                type: string
                                enum:
                                  - application/pdf
                                  - image/jpeg
                                  - image/png
                                  - image/webp
                                  - image/gif
                                  - image/avif
                                  - image/heic
                                  - image/heif
                                  - image/tiff
                                  - image/bmp
                              Content-Length:
                                type: string
                                minLength: 1
                                maxLength: 20
                            required:
                              - Content-Type
                              - Content-Length
                            additionalProperties: false
                          expires_at:
                            $ref: '#/components/schemas/Schema_7e459b62f3fc___schema0'
                        required:
                          - method
                          - url
                          - headers
                          - expires_at
                        additionalProperties: false
                      - type: 'null'
                  idempotent_replay:
                    type: boolean
                required:
                  - catalog_version
                  - attachment
                  - upload
                  - idempotent_replay
                additionalProperties: false
        '401':
          description: UNAUTHORIZED
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: FORBIDDEN
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: NOT_FOUND
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '408':
          description: TIMEOUT
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            VERSION_CONFLICT, IDEMPOTENCY_CONFLICT, DAILY_TOTAL_EXISTS,
            CATALOG_VERSION_MISMATCH
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: LIMIT_EXCEEDED
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: VALIDATION_ERROR
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: UNAVAILABLE
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - staticKey: []
        - apiKey: []
components:
  schemas:
    Schema_7e459b62f3fc___schema0:
      type: string
      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|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$
    Error:
      type: object
      additionalProperties: false
      required:
        - code
        - message
        - catalog_version
        - issues
      properties:
        code:
          type: string
          enum:
            - VALIDATION_ERROR
            - NOT_FOUND
            - VERSION_CONFLICT
            - IDEMPOTENCY_CONFLICT
            - DAILY_TOTAL_EXISTS
            - CATALOG_VERSION_MISMATCH
            - LIMIT_EXCEEDED
            - UNAUTHORIZED
            - FORBIDDEN
            - RATE_LIMITED
            - UNAVAILABLE
            - TIMEOUT
            - INTERNAL_ERROR
        message:
          type: string
        catalog_version:
          type: string
        issues:
          type: array
          items:
            type: object
            properties:
              path:
                type: string
              reason:
                type: string
              message:
                type: string
              suggested_keys:
                type: array
                items:
                  type: string
              discovery:
                type: object
        existing_id:
          type: string
        current_version:
          type: integer
        current_catalog_version:
          type: string
  securitySchemes:
    staticKey:
      type: http
      scheme: bearer
      description: >-
        Environment AUTH_KEY. Full ledger access and primary API-key
        administration. Not OAuth or JWT.
    apiKey:
      type: http
      scheme: bearer
      description: >-
        Generated opaque vlk_ key with a required name, explicit read/edit
        permissions, optional administrative inspection and chosen expiry
        (including Never). Enforces the same ceiling on REST and MCP; cannot
        administer credentials or account settings. Not OAuth or JWT.

````

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