Upload supporting documents
Attaching a document takes two separate requests:
POST /documents/upload-url: Garfield returns a short-lived (15-minute) signedupload_url. No file is sent here; this call is JSON metadata only.PUT <upload_url>: you send the file bytes straight to storage (Google Cloud Storage), not to Garfield.
Do both before POST /claims, and use the same partner_claim_id on
both API calls: POST /documents/upload-url and the later POST /claims (the
PUT itself carries no partner_claim_id). That is how the upload path is scoped
to the claim (see POST /claims).
Step 1: request the signed URL
Required: entity_id, partner_claim_id, filename, mime_type. max_bytes is
optional (default and cap 50 MB).
Allowed mime_type: application/pdf, image/jpeg, image/png, image/heic,
image/heif, image/webp, image/tiff, image/gif, application/msword, and
application/vnd.openxmlformats-officedocument.wordprocessingml.document (.docx).
curl -X POST "$BASE/documents/upload-url" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entity_id": "aZ4kQ9pX2",
"partner_claim_id": "case-2026-00412",
"filename": "invoice-00412.pdf",
"mime_type": "application/pdf",
"max_bytes": 5242880
}'
Response (201 Created):
{
"upload_url": "https://storage.googleapis.com/...",
"storage_path": "entities/aZ4kQ9pX2/claims/pc_af66fa4b5cb7283356863b7554d4e140/documents/0TCsxImkxYI.pdf",
"method": "PUT",
"expires_at": "2026-05-31T15:19:05.000Z",
"required_headers": {
"Content-Type": "application/pdf",
"x-goog-content-length-range": "0,5242880"
}
}
Step 2: upload the file
Send the file to the upload_url, echoing required_headers exactly. This is
a separate request to Google Cloud Storage: no bearer token, and it is
PUT-only (opening the URL in a browser returns MalformedSecurityHeader).
curl -X PUT "<upload_url>" \
-H "Content-Type: application/pdf" \
-H "x-goog-content-length-range: 0,5242880" \
--data-binary @invoice-00412.pdf
Then pass each returned storage_path in the claim's document_refs. At claim
time each storage_path must sit under the entity+claim prefix and the file must
already be uploaded; otherwise POST /claims fails with document_path_invalid
or document_not_uploaded respectively.