Skip to main content

Attachments and documents

A declaration can carry supporting documents, such as an invoice, a packing list or a certificate of origin. ITS can also render any version of a declaration as the adopted AfCFTA Transit Document.

Attach supporting documents

POST /etd/{serial_no}/attachments

Send the files as multipart/form-data:

PartRequiredNotes
fileYesOne document. Repeat the part to send several.
document_typeNoWhat kind of document these are, in your own words, such as INVOICE, PACKING_LIST or CERTIFICATE_OF_ORIGIN. It applies to every file in the request.
curl --fail-with-body --silent --show-error \
--cert "$ITS_CLIENT_CERT" --key "$ITS_CLIENT_KEY" \
--header "Authorization: Bearer $ITS_TOKEN" \
--form "file=@invoice.pdf" \
--form "file=@packing-list.pdf" \
--form "document_type=INVOICE" \
"$ITS_GATEWAY_URL/etd/KEMBATD26081138/attachments"

A successful call answers 201 with the declaration's attachments after the act.

Send the whole set in one request. Each request is one act: it appends one version of the declaration and announces it once to every country the declaration concerns. Twelve pages sent one at a time would make twelve versions and twelve announcements for every other country to receive and acknowledge.

  • Who may attach: any country the declaration concerns, not only the departure country, with the etd:attach permission. A REC may attach for the members it acts for.
  • All or nothing: nothing is stored unless every file in the request is accepted.
  • Type is checked from the content: ITS detects each file's type from its bytes, not from the header you send. A file whose content contradicts its declared type is refused, and so is a type this deployment does not accept.
  • Retries are harmless: a file ITS already holds is identified by its digest and returned rather than stored twice.
  • There is no delete: an attachment is evidence. Supersede it by attaching another.
StatusMeaning
201Stored
400No file sent, or a file was empty (VAL-ETD-037)
403You may see the declaration but not add to it (AUTHZ-ETD-036)
404No such declaration in your scope
413A file is larger than this deployment accepts
415A file is not an accepted type, or is not what it claims to be
503The deployment cannot scan files right now. Not your fault; try again later.

List the attachments

GET /etd/{serial_no}/attachments

Each entry carries:

FieldMeaning
sha256The lowercase hex SHA-256 of the file's bytes
filenameThe name the file was uploaded under, for display only
document_typeThe document_type it was attached with

The same list is inside the signed document, as envelope.attachments, on every read. There is no include=attachments: you already have it.

Download an attachment

GET /etd/{serial_no}/attachments/{attachment_id}/download

The file is streamed through ITS under the same authorisation as every other read, with Cache-Control: private, no-store.

Verify what you receive. Hash the bytes and compare them with the sha256 in envelope.attachments. If they differ, the file is not the one the declaration was signed with.

GET /etd/{serial_no}/pdf
GET /etd/{serial_no}/versions/{version_no}/pdf

Both need etd:read, the same permission as reading the JSON. The response is application/pdf: the adopted AfCFTA Transit Document, two A4 leaflets with 44 numbered boxes, rendered from the version's stored, signed content.

QueryValuesDefault
leafletI, II or BOTHBOTH
langA language tag for the box captionsEnglish
dispositionattachment or inlineattachment
as_ofAn instant, on the current-version route onlyThe current version

leaflet I is the declarant's segment and leaflet II the customs office segment, so each prints alone. An unknown leaflet or lang value is 400 VAL-ETD-058.

disposition changes only the Content-Disposition header. Use inline when you hand the URL to a viewer that renders in place.

curl --fail-with-body --silent --show-error \
--cert "$ITS_CLIENT_CERT" --key "$ITS_CLIENT_KEY" \
--header "Authorization: Bearer $ITS_TOKEN" \
--output KEMBATD26081138.pdf \
"$ITS_GATEWAY_URL/etd/KEMBATD26081138/pdf?leaflet=BOTH"

What the printed document shows

  • Boxes 43 and 44 show one country's leg. They carry the office of entry and the office of exit of the last country to have stamped at or before the version you print. To print an earlier leg, print an earlier version.
  • Every date is when ITS received a stamp. The captions say RECORDED BY AfCFTA ITS. They are not the time somebody signed.
  • No handwritten signature is drawn or imitated. The signature boxes carry the officer and station your administration supplied, with an attestation that ITS sealed the version. It is not the officer's own signature.
  • A transit ITS closed itself says so. The closing row on leaflet II is marked, with the words NOT EVIDENCE OF ARRIVAL.
  • Captions follow lang; values never change. A name filed in Arabic prints in Arabic inside an English-captioned form. A right-to-left language right-aligns the fields without reversing the box order.

Caching the PDF

ITS renders the PDF on request and keeps no copy. The same request reproduces the same document later, so keep the copy you were served if you need one.

The PDF's ETag is weak, W/"<content-hash>.<render-revision>.<leaflet>.<language>", and is not the version's content hash. Send it back as If-None-Match to get a 304.

warning

Never send the PDF's ETag as If-Match on an amendment. Take If-Match from GET /etd/{serial_no}, or the amendment is refused with 412.

Someone without an ITS account, such as a declarant, can download the current leaflet through the public route. See Verify and track.