Skip to main content

Document sourceSystem / sourceSystemId pair constraint

On documents, the check constraint documents_source_system_pair_nullity_chk requires both fields to be set or both to be null. Setting only sourceSystem without sourceSystemId fails with:
The simplest pattern: always pass a sourceSystemId alongside sourceSystem. If you don’t have a meaningful external id for a document, generate one (e.g. a UUID, or <your-system>_doc_<timestamp>).

Document upload: two-step presigned URL

Use the two-step presigned flow for document uploads β€” for carrier-invoice documents it’s the only path that runs AI classification: a combined or UNKNOWN PDF sent through an inline-base64 endpoint is filed but never classified or parsed, so nothing populates from it. (The base64 endpoints also reject payloads past a few MB.) The flow:
  1. POST /api/rest/generate-upload-presigned-url with { associationType, associationId, documentType, fileName, mimeType, sourceSystem, sourceSystemId } returns { documentId, uploadUrl }.
  2. PUT the file bytes directly to uploadUrl.
The presigned URL is signed for host-only headers. You can send Content-Type on the PUT, but avoid adding headers that aren’t in X-Amz-SignedHeaders. Wrapping the body in a Blob with an explicit type can cause some Node fetch implementations to add headers that break the signature β€” passing an ArrayBuffer is the safe path. Full upload mechanics: Document conventions.

Rate confirmations: customer vs. carrier

A customer rate confirmation and a carrier rate confirmation are two separate document types in Upwell β€” separate documentType values, separate parsers, and separate storage. Sending the correct one matters: Type a carrier rate confirmation as CARRIER_RATE_CONFIRMATION and a customer rate confirmation as CUSTOMER_RATE_CONFIRMATION. Each is AI-parsed on upload (through the two-step presigned flow above) by its own parser into its own storage, including the total rate. A document typed as one is never parsed, stored, or evaluated as the other.
Never label a carrier rate confirmation as CUSTOMER_RATE_CONFIRMATION (or vice versa). The carrier rate is your cost/margin and must never reach the customer. If a rate confirmation is mis-typed on upload, re-type the document and re-process it rather than editing the parsed amount.