Files and attachments
Attachments do not pass through this API. You ask for an upload URL, send the bytes straight to storage, and then confirm. Three calls, and large files never touch the API.
POST /v1/files/presign ask for a URL
PUT <upload_url> send the bytes
POST /v1/files/confirm make it real
1. Presign
curl -s -X POST "$BASE/files/presign" \
-H "x-api-key: $API_KEY" \
-H "X-On-Behalf-Of: dr.chen@example.gov" \
-H "Content-Type: application/json" \
-d '{
"filename": "physician-certificate.pdf",
"content_type": "application/pdf",
"resource_type": "ATTACHMENT",
"resource_id": "9d2b6e14-6f1a-4a1c-9c0e-6f5f4b3a2d10"
}'
{
"file_id": "51d3c8a4-9e2b-4d17-a6f0-3b8c5e1f7d29",
"upload_url": "https://uploads.warrants.ecourtdate.com/…?signature=…",
"storage_key": "agencies/4f0c9d2e/warrants/9d2b6e14/physician-certificate.pdf",
"expires_in": 900
}
resource_type says what the file is attached to. Use ATTACHMENT with the
warrant's id in resource_id for evidence and certificates, and
TEMPLATE_DOCUMENT for a file that will back a
template.
upload_url is valid for expires_in seconds. Presign immediately before
uploading, not in advance.
2. Upload
curl -s -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @physician-certificate.pdf
Send the same Content-Type you presigned with, or the upload is rejected. Do
not send your API key to the upload URL: it is already authorized, and the URL
goes to a different host.
3. Confirm
curl -s -X POST "$BASE/files/confirm" \
-H "x-api-key: $API_KEY" \
-H "X-On-Behalf-Of: dr.chen@example.gov" \
-H "Content-Type: application/json" \
-d '{
"file_id": "51d3c8a4-9e2b-4d17-a6f0-3b8c5e1f7d29",
"storage_key": "agencies/4f0c9d2e/warrants/9d2b6e14/physician-certificate.pdf"
}'
Confirmation checks that the bytes actually arrived and makes the attachment part of the application. An attachment that is never confirmed does not exist as far as the warrant is concerned: it will not appear on the application, on the document, or in a public link. If an upload fails, presign again rather than confirming a file that did not land.
Listing and downloading
curl -s "$BASE/files?resource_type=ATTACHMENT&resource_id=$WARRANT_ID" \
-H "x-api-key: $API_KEY"
curl -s "$BASE/files/$FILE_ID" -H "x-api-key: $API_KEY" | jq -r .download_url
download_url is short-lived and signed, like pdf_url. Re-read the file
record for a fresh one instead of caching the URL. Each download is written to
the audit trail.
The attachments on an application also come back inline on the warrant response, so a single fetch usually answers everything.
Deleting
curl -s -X DELETE "$BASE/files/$FILE_ID" \
-H "x-api-key: $API_KEY" \
-H "X-On-Behalf-Of: admin.reyes@example.gov"
The record and the stored object are both removed. The audit trail keeps the record that the file existed and who removed it.
Think before deleting attachments on a signed warrant: they are part of what was presented to the court.
Practical limits
- Presigned URLs expire in minutes, not hours.
- Send a real
content_type; it is what a browser uses to display the file. - Attach files to an application before it is submitted, so reviewers see the complete picture when they open it.