Skip to main content

Documents API

Generate trade documents from shipment data. Documents are generated asynchronously — the endpoint returns job IDs that you poll for completion.

info

Document generation is asynchronous. The endpoint returns 202 Accepted with job IDs. Poll the jobs table or use webhooks to track completion.

Generate Documents

POST /functions/v1/generate-documents

Request Body

FieldTypeRequiredDescription
shipmentobjectYesThe full shipment data object
document_typesstring[]YesArray of document type keys to generate
shipment_idstringNoShipment UUID. When provided, enables regeneration tracking with tier-based generation limits.
final_docbooleanNoWhen true, all fields render as static text. When false or omitted, empty fields become fillable PDF form fields. Default: false.
confirm_warningsbooleanNoSet to true to bypass soft warnings (missing optional fields). Default: false.
validation_hashstringNoSHA-256 hash from a prior validation run. Embedded in document footers for verification.
previous_shipment_dataobjectNoPrevious shipment data for diff computation on regeneration. Only used when shipment_id is provided.

Example Request

curl -X POST "https://<project-ref>.supabase.co/functions/v1/generate-documents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "apikey: YOUR_ANON_KEY" \
-d '{
"shipment": {
"exporter": { "name": "Acme Corp" },
"importer": { "name": "Global Trade GmbH" },
"route": { "origin_country": "US", "destination_country": "DE" },
"goods": { "currency": "USD", "total_value": 25000, "line_items": [] }
},
"document_types": ["COMMERCIAL_INVOICE", "PACKING_LIST"],
"validation_hash": "a1b2c3d4..."
}'

Available Document Types (16)

Core Trade Documents

TypeDescription
COMMERCIAL_INVOICECommercial invoice
PACKING_LISTPacking list
BILL_OF_LADINGBill of lading
CERTIFICATE_OF_ORIGINCertificate of origin
PROFORMA_INVOICEProforma invoice
DANGEROUS_GOODS_DECLARATIONDangerous goods declaration (DGD)
AIR_WAYBILLAir waybill

Logistics & Financial

TypeDescription
SHIPPERS_LETTER_OF_INSTRUCTIONShipper's letter of instruction
VGM_DECLARATIONVerified gross mass declaration (SOLAS)
INSURANCE_CERTIFICATEMarine cargo insurance certificate

Preferential Trade Agreements

TypeDescription
EUR1_MOVEMENT_CERTIFICATEEUR.1 movement certificate (EU FTA partners)
USMCA_CERTIFICATE_OF_ORIGINUSMCA certificate of origin (US/CA/MX)
STATEMENT_ON_ORIGINStatement on origin (EU FTA)

Commodity-Specific Certificates

TypeDescription
PHYTOSANITARY_CERTIFICATEPhytosanitary certificate (plant products)
HEALTH_VETERINARY_CERTIFICATEHealth / veterinary certificate (animal products)
CERTIFICATE_OF_ANALYSISCertificate of analysis (lab-tested products)

Response (Success — 202)

{
"jobs": [
{
"jobId": "uuid-1234",
"docType": "COMMERCIAL_INVOICE",
"rynkoJobId": "rynko-job-5678"
},
{
"jobId": "uuid-5678",
"docType": "PACKING_LIST",
"rynkoJobId": "rynko-job-9012"
}
],
"generation_count": 2,
"max_generations": 10,
"generation_history_id": "uuid-hist-1234"
}

The generation_count, max_generations, and generation_history_id fields are only present when shipment_id is provided.

Response (Pre-Check Errors — 400)

Hard errors that block generation. All errors across all requested document types are collected and returned at once.

{
"success": false,
"preCheckErrors": [
{
"docType": "DANGEROUS_GOODS_DECLARATION",
"errors": [
{
"message": "No line items flagged as hazardous",
"fieldPath": "goods.lineItems.0.complianceFlags",
"tab": "goods"
},
{
"message": "Emergency contact required for DGD",
"fieldPath": "hazardousShipment.emergencyContact",
"tab": "hazardous"
}
]
}
]
}

Response (Soft Warnings — 200)

Warnings for missing optional fields. The document can still be generated — the fields will be blank. Re-submit with confirm_warnings: true to proceed.

{
"success": false,
"requiresConfirmation": true,
"warnings": [
{
"docType": "BILL_OF_LADING",
"warnings": [
{
"message": "Freight payment terms not set (PREPAID/COLLECT)",
"fieldPath": "blData.freightPayment",
"tab": "logistics"
},
{
"message": "Place of delivery not set",
"fieldPath": "blData.placeOfDelivery",
"tab": "logistics"
}
]
}
]
}

Pre-Check Validation Rules

The following document types have mandatory pre-checks that block generation if conditions are not met.

DANGEROUS_GOODS_DECLARATION

  • At least one line item must be flagged as hazardous (compliance_flags includes dgd or is_hazardous: true)
  • Each hazardous line item must have un_number and hazard_class
  • hazardous_shipment.emergency_contact is required

HEALTH_VETERINARY_CERTIFICATE

  • veterinary_data.competent_authority is required
  • veterinary_data.establishment_number is required

PHYTOSANITARY_CERTIFICATE

  • phytosanitary_data.issuing_authority is required

CERTIFICATE_OF_ANALYSIS

  • analysis_data.batch_number is required
  • analysis_data.test_standard is required

EUR1_MOVEMENT_CERTIFICATE

  • Destination country must be an EU FTA partner (EU member states plus CH, NO, IS, LI, TR)
  • Origin country must not be US (no EU preferential trade agreement)

STATEMENT_ON_ORIGIN

  • Same rules as EUR.1 Movement Certificate

USMCA_CERTIFICATE_OF_ORIGIN

  • Destination country must be US, CA, or MX

Soft Warning Rules

The following document types produce soft warnings for missing optional fields. These do not block generation but indicate that fields will be blank on the generated document.

Document TypeWarning Fields
BILL_OF_LADINGbl_data.freight_payment, bl_data.place_of_delivery
INSURANCE_CERTIFICATEinsurance_data.insurance_company, insurance_data.policy_number, insurance_data.coverage_type, insurance_data.claims_agent
VGM_DECLARATIONvgm_data.weighing_method, vgm_data.authorised_person, vgm_data.weighing_station
SHIPPERS_LETTER_OF_INSTRUCTIONsli_data.forwarding_agent_name, sli_data.eei_filing
AIR_WAYBILLawb_data.issuing_carrier, awb_data.agent_name

Regeneration

When shipment_id is provided, the endpoint tracks generation attempts and enforces tier-based limits. Each call atomically increments the shipment's generation_count. If the limit is exceeded, the endpoint returns 429.

A generation_history record is created for each regeneration, including:

  • A snapshot of the shipment data at generation time
  • A diff against previous_shipment_data (if provided)
  • The list of document types generated
  • The validation hash used

Error Codes

HTTP StatusError CodeDescription
400KLV_VAL_002shipment and document_types are required
404KLV_SHIP_004Shipment not found (when shipment_id is provided)
409KLV_GEN_LIMITConcurrent generation detected — retry
429KLV_GEN_LIMITGeneration limit exceeded for this shipment. Upgrade your plan.

Polling Strategy

Poll the Supabase jobs table every 2 seconds for each job ID:

async function waitForDocument(jobId) {
for (let i = 0; i < 30; i++) {
const { data: job } = await supabase
.from('jobs')
.select('id, status, rynko_job_id, error_message')
.eq('id', jobId)
.single();

if (job.status === 'completed') return job;
if (job.status === 'failed') throw new Error(job.error_message);

await new Promise(r => setTimeout(r, 2000));
}
throw new Error('Generation timed out');
}