Skip to main content

Manage evidence

Attach the documents that support the dispute before you submit it. Documents can only be added, replaced, or removed while the dispute is in draft. They become immutable the moment you submit.

Upload a document

Uploading is a three-step handoff: you never send the file bytes to this API directly. Instead you get a pre-signed URL, PUT the file straight to storage, then confirm.

1. Start the upload. Call Upload an evidence document with the file's name, content type, exact size, and an evidence_type — no file bytes yet:

curl -X POST "https://api.openfabric.co/v1/disputes/b16a7072-3deb-46d3-aad0-5b95da03e8e4/documents" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"file_name": "delivery-estimate.pdf",
"content_type": "application/pdf",
"size_bytes": 184320,
"evidence_type": "expected_delivery_date"
}'

A size_bytes over the 14.5MB limit is rejected here with 400, before any bytes move.

Sample response — the document is created in pending status, with a short-lived upload_url. size_bytes is your declared value until step 3 corrects it to whatever storage actually received:

{
"document_id": "3c1a7b2e-9f4d-4e8a-8c3b-1a2f9d6e7c5b",
"dispute_id": "b16a7072-3deb-46d3-aad0-5b95da03e8e4",
"evidence_type": "expected_delivery_date",
"file_name": "delivery-estimate.pdf",
"content_type": "application/pdf",
"size_bytes": 184320,
"status": "pending",
"is_immutable": false,
"upload_url": "https://dev-dispute-evidence-064432445227.s3.ap-southeast-1.amazonaws.com/...(signed)...",
"created_at": "2026-07-08T13:05:00Z",
"updated_at": "2026-07-08T13:05:00Z"
}

2. PUT the file to upload_url, with a Content-Type header matching what you declared in step 1 exactly, and a body of exactly size_bytes long — the URL is signed for both, so a mismatch is rejected:

curl -X PUT "<upload_url from the response above>" \
-H "Content-Type: application/pdf" \
--data-binary @delivery-estimate.pdf

3. Confirm the upload. Call Complete an evidence document upload, which verifies the file actually landed in storage, corrects size_bytes to the real value read back from storage, and flips the document to uploaded. Returns 409 upload_not_confirmed if the file hasn't been PUT yet — retryable, unlike the 409 conflict you'd get from calling any of these while the dispute isn't draft.

curl -X POST "https://api.openfabric.co/v1/disputes/b16a7072-3deb-46d3-aad0-5b95da03e8e4/documents/3c1a7b2e-9f4d-4e8a-8c3b-1a2f9d6e7c5b/complete" \
-H "Authorization: Bearer <access_token>"

A document stuck in pending (step 2 or 3 never happened) doesn't count toward the checklist and doesn't have a working download_url yet. Delete it (see below) and start over with a fresh upload rather than leaving it behind — an abandoned pending document still occupies its evidence_type slot as far as this API can tell.

Files up to 14.5MB are accepted as PDF, JPEG, JPEG 2000, TIFF, PNG, or HEIC. evidence_type must be one that the reason code of this dispute accepts (see the table below); anything else is rejected with 400, as is a content_type outside the accepted set.

Evidence types by reason code

reason_codeAccepted evidence_type values
fraud_unauthorized_card_not_presentfraud_attestation
goods_not_receivedexpected_delivery_date, proof_merchant_contacted
defective_not_as_describedproof_of_defect, proof_merchant_contacted
digital_goods_not_receivedscreenshots, account_evidence, merchant_comms
refund_not_processedproof_refund_promised, cancellation_comms
recurring_after_cancellationproof_of_cancellation, cancellation_timestamp
duplicate_processingreceipt_comparison
incorrect_amountreceipt_or_invoice

A reason code can mark some of its evidence types as required and others as recommended. Required types are listed in required_documents on the dispute and submit fails until each one is present; recommended types (recommended_documents) strengthen the case but are optional. Check checklist.satisfied and checklist.missing_required on the dispute or on the document list response to know where you stand.

List documents

List evidence documents returns every document attached to the dispute, plus the current checklist state. download_url is not populated on list items, so fetch a single document to get one.

Get an evidence document returns the same metadata plus a short-lived, pre-signed download_url:

{
"document_id": "3c1a7b2e-9f4d-4e8a-8c3b-1a2f9d6e7c5b",
"file_name": "delivery-estimate.pdf",
"download_url": "https://dev-dispute-evidence-064432445227.s3.ap-southeast-1.amazonaws.com/...(signed)...",
"is_immutable": false
}

The link expires, so fetch a fresh download_url right before you use it rather than caching it.

Replace or remove a document

While the dispute is still in draft:

  • Replace an evidence document swaps the file on an existing document, keeping the same document_id and evidence_type. It follows the same three-step handoff as a new upload: call it with a new file_name/content_type to get a fresh upload_url (the document goes back to pending), PUT the new file there, then call complete again.
  • Delete an evidence document removes it entirely.

Both return 409 once the dispute has been submitted.

Next: Submit and track.