Skip to content
API Now! is currently in closed beta. We are constantly updating these guides as we release updates!

File Uploads

API Now! uses a highly optimized, secure, and opinionated Two-Phase Upload Mechanism to manage files, attachments, and images.

Rather than sending heavy binary payloads (like multipart forms) directly to your CRUD endpoints, clients obtain a secure signed upload URL, upload the file directly to storage, and then associate the uploaded file reference with database records.


The file upload workflow operates in three distinct phases:

sequenceDiagram
    autonumber
    Client->>API Gateway: 1. POST /.well-known/upload (filename, contentType)
    API Gateway->>Client: Returns file_reference (token) & upload_url
    Client->>Storage Disk: 2. PUT upload_url (raw binary payload)
    Client->>API Gateway: 3. POST /collectionPath (payload includes file_reference token)
    API Gateway->>Storage Disk: Promotes file from tmp/ to uploads/

Before sending any file content, the client must notify the API of its intent to upload. The client sends a POST request to the platform’s well-known upload endpoint:

  • Endpoint: POST /api/:apiSlug/:version/.well-known/upload
  • Request Body:
    {
    "filename": "invoice_2026.pdf",
    "contentType": "application/pdf"
    }
  • Response:
    {
    "file_reference": "nZ3x8La19s_K",
    "upload_url": "https://storage.googleapis.com/your-bucket/tmp/org/nZ3x8La19s_K.pdf?GoogleAccessId=..."
    }

The client makes a standard PUT request containing the raw binary file payload directly to the upload_url received in Phase 1:

  • Request Method: PUT to the upload_url
  • Headers: Must include the matching Content-Type specified during Phase 1.
  • Expiration: The signed URL expires automatically after 15 minutes.

Phase 3: Save the Reference in the Database

Section titled “Phase 3: Save the Reference in the Database”

Once the binary upload to the storage disk finishes successfully, the client sends a CRUD request (such as POST /invoices) to save the database record. Instead of transmitting the file data, the client simply supplies the file_reference string token as the property value:

  • Request Body:
    {
    "invoice_number": "INV-10204",
    "attachment_file": "nZ3x8La19s_K"
    }

When you associate the file_reference with a property annotated with the ImageURL or FileURL semantics, the engine runs several automated routines:

  • Validation: The engine verifies that the file_reference token exists in the temporary table and that the file has been successfully uploaded.
  • Promotion: The engine copies the file from its temporary path (tmp/) to its permanent folder (uploads/), cleans up the temporary files, and updates the database column.
  • Database Metadata Storage: The database does not store the raw URL; instead, it stores a structured JSON metadata block:
    {
    "id": "nZ3x8La19s_K",
    "location": "uploads/org/nZ3x8La19s_K.pdf",
    "name": "invoice_2026.pdf",
    "mime": "application/pdf"
    }
  • Temporary Retrieval Links: When clients query records (e.g. GET /invoices/1), the engine intercepts the metadata and generates a secure, temporary 15-minute signed URL with correct inline headers. This keeps your files private and prevents public link harvesting.
  • Automatic Deletions: If a record is updated with a new file or hard-deleted, the engine automatically deletes the old file from the storage disk to save space and maintain hygiene.

When attaching the FileURL or ImageURL semantic module to a Binary or String property, you can configure standard validations:

  • File Size Validation (maxSizeInBytes): Restricts the maximum permitted size of the uploaded file. If the uploaded file exceeds this limit, the CRUD action (POST/PUT/PATCH) will fail with a 422 Validation Error (e.g., "The field 'file_pointer' file size exceeds the maximum allowed size...").
  • Mime Type Validation (allowedMimeTypes): Restricts the allowed file mime types (e.g., ['application/pdf'] or ['image/png', 'image/jpeg']). If the uploaded file has a different content type, the CRUD request will fail with a 422 Validation Error.