Skip to main content
In this guide, you upload a PDF file to sajn and attach it to a draft document. The bytes go straight to storage through a presigned URL, so the API server never handles them.

Before you begin

  • Store your API key in the SAJN_API_KEY environment variable. To create a key, go to workspace settings in the sajn app, then Utvecklare (Developer) > API-nycklar (API keys).
  • Have a DRAFT document. For more information, see Create a document.
  • Have a file of at most 25 MB (26,214,400 bytes) in a supported format. sajn accepts PDF, Word, Excel, and PowerPoint documents; JPEG, PNG, GIF, WebP, and SVG images; and MP4, QuickTime, AVI, and WebM video. For the exact MIME types, see Create a file.

How the upload works

  1. You create a file record with the file’s name, MIME type, size, and SHA-256 checksum. The response is the file, with its id, a storage key, and an uploadUrl.
  2. You send the bytes to uploadUrl in a PUT request. Storage rejects bytes that don’t match the checksum.
  3. You confirm the upload, so sajn verifies the stored bytes.
  4. You reference the storage key in a document field.

Upload a file and attach it

1

Compute the checksum

The checksum is the SHA-256 hash of the exact bytes you upload, encoded as base64:
2

Create the file record

Send a POST request to /api/v1/files:
The response is the file, in the same shape as Get file by ID, plus key and uploadUrl. The following example leaves out url and uploadedBy:
uploadUrl is valid for 15 minutes. visibility is optional: PRIVATE, the default, serves the file only through short-lived signed URLs, and PUBLIC serves it from a permanent URL.
3

Upload the bytes

Send the file to uploadUrl with the same Content-Type and the checksum in the x-amz-checksum-sha256 header. Don’t send your Authorization header; the URL is already signed:
Replace UPLOAD_URL with the uploadUrl from the previous step. A successful upload returns an empty 200 response.
4

Confirm the upload

Confirm the file, so sajn verifies the stored size and checksum before you use it:
Replace FILE_ID with the file id. sajn checks the stored size and, when storage records it, the checksum. The response is the file, in the same shape as Get file by ID.Confirming is idempotent. If you skip it, sajn confirms the file the first time you call Get file by ID.
5

Attach the file to the document

Create a PDF field whose fieldMeta.value is the storage key:
Replace the following:
  • DOCUMENT_ID: the ID of the draft document.
  • STORAGE_KEY: the key from the file record.
The response has the created field in data, in the same shape as Get a document field. To replace the PDF of an existing field, send a PATCH request to /api/v1/documents/DOCUMENT_ID/fields/FIELD_ID with the full fieldMeta.To place signature boxes and input fields on the PDF’s pages, see Place fields on a PDF.

Complete example

The following programs run the whole flow for contract.pdf. Set SAJN_API_KEY and DOCUMENT_ID in the environment first:

Handle errors

  • 400 VALIDATION_FAILED on POST /api/v1/files: the mimeType isn’t supported, or size is more than 26,214,400 bytes. The issues array names the field.
  • 403 from the uploadUrl: the URL expired, or the Content-Type doesn’t match mimeType. Create a new file record.
  • 400 from the uploadUrl: the bytes don’t match the checksum. Compute the size and the checksum from the same bytes you upload.
  • 401 UNAUTHORIZED on a sajn endpoint: the Authorization header is missing or the key is invalid. The uploadUrl doesn’t take the header.
For the error shape and every code, see Errors.

Next steps

Place fields on a PDF

Add signature boxes and inputs to the uploaded PDF.

Send for signing

Send the document to its parties.

Create a file

See the endpoint in the API reference.

Confirm an uploaded file

See the endpoint in the API reference.