ModulesDocuments, PDFs & Integrations
Modules

Documents, PDFs & Integrations in Jules

How Jules generates commercial documents, manages templates, verifies uploaded files with AI, and integrates with external systems via email and webhooks.

Product documentation — How Jules generates, stores, and distributes commercial documents (POs, SOs, invoices, and more), manages document templates and legal terms, handles Letter of Credit workflows, and connects with external systems through email and webhooks.


Table of Contents

  1. Overview

  2. Document Types (DocType)

  3. PDF Templates

  4. Document Terms (DocTerm)

  5. Site-Level PDF Parameters

  6. PDF Generation Workflow

  7. Uploaded Documents & Manual Upload

  8. Document Approval Workflow

  9. AI Document Verification & Mismatch Detection

  10. Document Receivables (DocReceivables)

  11. Letter of Credit

  12. Email Integration

  13. Webhook System

  14. Relationships with Other Modules

  15. Key Business Rules

  16. Glossary


Overview

Jules has a complete document management layer that covers the full lifecycle of commercial paperwork — from generating a Purchase Order the moment a deal is confirmed, to distributing it to a counterparty by email, to verifying a Bill of Lading uploaded by the supplier against Jules data using AI.

The document system is built on four interconnected concepts:

ConceptDescription
PDFAn individual document record — either generated by Jules or uploaded manually
PdfTemplateA reusable configuration that defines how a document is rendered
DocTypeThe category of a document (Purchase Order, Invoice, Bill of Lading, etc.)
LinkedEntityThe Jules object the document is attached to (operation, invoice, container, etc.)

Document Types (DocType)

Every document in Jules belongs to a DocType — a fixed category that determines its purpose, how it is rendered, and which entities it can be attached to.

DocTypeDescriptionTypical linked entity
PURCHASE_ORDERSent to a supplier to confirm a purchaseOperation (BUY)
SALES_ORDERSent to a customer to confirm a saleOperation (SELL)
CUSTOMER_INVOICEInvoice issued to a customerInvoice
SUPPLIER_INVOICEInvoice received from a supplierInvoice
CUSTOM_INVOICECustom invoice formatInvoice
INVOICE_PROFORMAPro-forma invoice before final pricingInvoice
BOOKING_CONFIRMATIONFreight booking confirmation sent to shipperFreight Booking
FREIGHT_BOOKING_REQUESTRequest for freight booking sent to a forwarderFreight Booking
PRE_CARRIAGE_BOOKING_REQUESTBooking request for pre-carriage transportPre-Carriage Booking
DELIVERY_ORDERAuthorization to release cargo at destinationContainer
DELIVERY_SLIPProof of delivery at destinationContainer
DELIVERY_REPORTCondition report at deliveryContainer
LOAD_REPORTLoading condition and weight reportContainer
LOADING_SLIPDocument confirming goods loadedContainer
ANNEX_7EU cross-border waste transfer documentContainer
CTN_ANNEX_7Container-level Annex 7Container
ISO_REPORTISO quality reportContainer
RECOVERY_CERTIFICATECertificate confirming material recoveryContainer
RECOVERY_NOTERecovery note for waste materialsContainer
CONTRACT_OFFERDocument version of an offer sent to a counterpartyOffer
SHARED_OFFEROffer document shared with a counterparty via portalOffer
SUPPLIER_INVOICEBill received from a providerInvoice
OTHERCatch-all for miscellaneous attachmentsAny

Note: RECOVERY_CERTIFICATE_EXCEL is generated client-side in the front-end and is not processed through the backend generation pipeline.


PDF Templates

A PdfTemplate is the configuration record that tells Jules how to render a document. Templates decouple the rendering logic from individual documents, so the same template can be reused across hundreds of operations.

Template fields

FieldDescription
templateIdThe ID of the underlying rendering template (used by the document generation service)
docTypeThe document type this template produces
docTypeNameA human-readable label for the document type
linkedEntityWhich entity type this template applies to (e.g., PURCHASE, SALE, INVOICE)
defaultFormatThe default output format: PDF, DOCX, or XLSX
isDefaultWhether this is the default template for its DocType + LinkedEntity combination
isPublicWhether this template is available to external/portal users
statusesA list of document statuses that get assigned when the document is created
priorityConfigJSON configuration for template selection priority logic
shouldCheckInvoiceBeforeGenerateWhen true, validates invoice data before generating the document
aiApiWhich AI verification pipeline to use (BL_VERIFICATION or LC_VERIFICATION)
receivablesWhich portal entity types can receive this document
descriptionOptional human-readable description

Supported output formats

FormatUse case
PDFStandard commercial documents, delivery slips, invoices
DOCXEditable Word documents for counterparties who need to redline
XLSXSpreadsheet-based reports (recovery certificates, weight reports)

Template scope by entity

Templates are scoped to a LinkedEntityEnum value, which controls which object type can use them:

All templates are fetched via filteredPdfTemplates with filters for linkedEntity, docType, and isDefault. The pdfTemplatesChoices query returns a dropdown-friendly list for the UI.


Document Terms (DocTerm)

DocTerms are the legal boilerplate paragraphs embedded in commercial documents — the standard terms and conditions, payment clauses, and legal notices printed at the bottom of POs, SOs, and invoices.

FieldDescription
valueShort identifier or key for the term
titleDisplay title of the clause
contentFull text of the legal clause
typeCategory of the term (e.g., payment, delivery, liability)
orderDisplay order within the document
tagOptional grouping tag
docTypesWhich document types include this term

DocTerms can be filtered by docType and billingEntity, allowing organizations that operate under multiple billing entities to maintain distinct sets of legal terms per entity. Terms are updated via updateDocTerm.


Site-Level PDF Parameters

When a user opens the document generation dialog for a purchase or sale operation, Jules pre-fills several fields from site-level configuration — the PoSoParams. These defaults are stored per site and per quality, and are fetched by the getPoSoParams query.

FieldDescription
paymentTermsDefault payment terms for this site
loadingScheduleExpected loading schedule text
portOfDestinationDefault destination port for this site
originCountry or region of origin
conditionningPackaging / conditioning description
blCommentDefault comment to appear on Bill of Lading
docGeneralCommentGeneral comment printed on the document
docsRequired document checklist (e.g., BL, packing list, COA)
logisticMaterialDefault equipment type

These parameters reduce repetitive data entry when generating routine POs and SOs.


PDF Generation Workflow

How a document is generated

Generation steps in detail

  1. Template selection: The user selects (or Jules auto-selects) a PdfTemplate for the document type.

  2. Argument pre-fill (pdfArgs): Jules fetches and pre-fills the data payload for the template — operation details, quality lines, counterparty information, site parameters, and legal terms. The user can review and override fields in the UI.

  3. Document creation: Jules calls the document generation service with the template ID, data payload, and output format. The service renders the document and returns a storage URL.

  4. JSON snapshot: A JSON copy of the data used to render the document is stored alongside the PDF, for audit purposes.

  5. PDF record creation: A Pdf record is created in Jules linking the document URL to the entity (operation, invoice, container, etc.) with the appropriate status.

Batch and aggregate generation

Jules supports batch generation — generating the same document for multiple entities in a single call. For example, generating delivery slips for all containers in a shipment at once.

It also supports aggregate generation (shouldGenerateAggregatePdf: true), which combines data from multiple entities into a single consolidated document. This is useful for multi-container shipment summaries.

Supported entities for generation

LinkedEntitySupported
PURCHASEYes — Purchase Orders
SALEYes — Sales Orders
INVOICEYes — Customer and supplier invoices
CONTAINERYes — Delivery slips, load reports, Annex 7
SHIPMENTYes — Shipment-level documents
FREIGHT_BOOKINGYes — Booking confirmations
PRE_CARRIAGE_BOOKINGYes — Pre-carriage requests
OFFERYes — Contract offers, shared offers
OPERATION_QUALITYYes — Quality-level documents
TRUCKYes — Truck-level delivery documents
REPORTS_LISTYes — Aggregate reports

Asynchronous generation

For large-scale generation (e.g., generating documents for all containers in a shipment), Jules uses generateEntityDocs, which pushes a job to the RabbitMQ worker queue (generateEntityDocs queue). The generation happens asynchronously in the background, so the user's session is not blocked.


Uploaded Documents & Manual Upload

Not all documents are generated by Jules. Counterparties send back signed POs, Bills of Lading, weight certificates, and other documents that must be stored in Jules.

The savePdfInfo mutation handles manual uploads:

FieldDescription
docTypeThe type of document being uploaded
docTypeNameOptional display name override
linkedEntityThe entity type this document belongs to
linkedEntityIdThe specific entity (operation, invoice, container)
urlThe storage URL of the uploaded file
nameDisplay name for the document
statusDocument status at upload time
uidFirebase UID of the uploaded file

PO/SO status auto-update on upload

When a signed document is uploaded back into Jules:

  • Uploading a PURCHASE_ORDER automatically updates the parent operation's poStatus to SIGNED_AND_UPLOADED

  • Uploading a SALES_ORDER automatically updates the parent operation's soStatus to SIGNED_AND_UPLOADED

This tracks the commercial document lifecycle without any manual status update.

PO/SO document lifecycle

StatusMeaning
PENDINGDocument not yet created
CREATEDDocument generated as PDF/DOCX in Jules
SENTDocument sent to the counterparty
SIGNED_AND_UPLOADEDSigned document uploaded back to Jules

Merging documents

Multiple PDF documents can be merged into a single file using the mergePdfs mutation. Jules calls the document service to combine the files (in the exact order of IDs provided) and creates a new Pdf record of type MERGED_DOCUMENTS linked to the same entities.

Marking documents complete

markAllAsComplete flags all documents attached to an entity as complete in a single operation. Useful when finalizing a shipment where multiple documents have been collected.


Document Approval Workflow

Some documents require internal review before being shared externally. Jules supports a structured approval workflow on PDFs.

How it works

  1. After generating a document, a user submits it for approval with insertPdfsToApprovers, specifying which users should review it. An optional requestComment can be included.

  2. Reviewers are notified (via RabbitMQ sendNotification queue, trigger ON_REQUEST_FOR_DOCUMENT_APPROVAL).

  3. Each approver can either approvePdf or rejectPdf (with a rejectComment explaining the issue).

  4. The reviewStatus field reflects the outcome: PENDING, APPROVED, or REJECTED.

  5. When the review is complete, a ON_DOCUMENT_REVIEWED notification is sent.

FieldDescription
isApprovableWhether the current user can approve/reject this document
reviewStatusPENDING, APPROVED, or REJECTED
verificationStatusOverall verification progress: PENDING, IN_PROGRESS, or COMPLETED
requestedByUser who requested the approval
requestCommentComment added when requesting approval
lastReviewedByUser who last approved or rejected
lastReviewedAtTimestamp of the last review action
rejectCommentReason for rejection
approvalRequestedAtWhen approval was first requested

AI Document Verification & Mismatch Detection

Jules includes an AI-powered document verification capability that compares uploaded documents against the data stored in Jules, highlighting discrepancies.

This is currently used for two verification types:

AI APIUse case
BL_VERIFICATIONVerifying a Bill of Lading against shipment and container data
LC_VERIFICATIONVerifying a Letter of Credit against operation terms

How AI verification works

The Mismatch record

Each detected discrepancy is stored as a Mismatch:

FieldDescription
pdfIdThe document that was verified
aiKeyThe field name that was checked (e.g., portOfLoading, containerNumber)
julesValueThe value Jules has on record
aiValueThe value extracted by the AI from the document
statusAPPROVED (the discrepancy is accepted) or REJECTED (flagged as an error)
issueTextHuman-readable description of the issue
improvementTextAI-generated suggestion for resolution

Reviewer actions on mismatches

Reviewers can:

  • Approve a mismatch (status: APPROVED) — acknowledging the discrepancy as acceptable

  • Reject a mismatch (status: REJECTED) — flagging it as a genuine error requiring correction

  • Update a mismatch — adding issue text, improvement suggestions, or correcting the Jules value

This workflow gives trade operations teams a structured way to review and sign off on incoming shipping documents before funds are released or goods cleared.


Document Receivables (DocReceivables)

DocReceivables defines which documents a counterparty (supplier or customer) is expected to provide for a given document type. It is a configuration table that maps associatedObjectType + docType combinations to required receivable items.

This is used to power the document checklist feature — showing operations teams which documents they are still waiting to receive from a counterparty, for example:

  • Bill of Lading from the shipping line

  • Weight certificate from the inspection company

  • Phytosanitary certificate from the supplier

The getByDocTypeAndAssociatedObjects query is used internally to look up what documents are expected for a given entity type and document category.


Letter of Credit

A Letter of Credit (LC) is a bank-issued financial guarantee commonly used in international commodity trade to ensure payment upon presentation of shipping documents.

Jules models Letters of Credit as first-class entities that can be created, managed, and linked to operations — particularly export sales where the buyer's bank issues an LC as payment security.

Letter of Credit fields

FieldDescription
lcNumberThe reference number of the LC
typeLC type (e.g., irrevocable, confirmed, standby)
statusCurrent status of the LC
lcAmountThe monetary value covered by the LC (with currency)
dateOfIssueDate the LC was issued
etdEstimated time of departure of the shipment
endDateExpiry date of the LC
periodPresentationNumber of days after shipment to present documents
paymentClausePayment terms embedded in the LC
detailsOfChargesWhich party bears banking charges (e.g., all charges to beneficiary)
incotermOnDocumentThe incoterm as stated on the LC
freeTimeFree days allowed at destination port
freeTimeConditionsConditions governing the free time
commentInternal notes about the LC
bankOfIssueName of the issuing bank (buyer's bank)
bankOfAdvisingName of the advising bank (seller's bank)
bankOfConfirmingName of the confirming bank (if LC is confirmed)
refNumberOfIssuingBankReference number at the issuing bank
refNumberOfAdvisingBankReference number at the advising bank
issuingBankAccountBank account record for the issuing bank
advisingBankAccountBank account record for the advising bank
costBankAccountBank account for banking cost charges
revenueBankAccountBank account where payment is received
billingEntityThe Jules billing entity associated with this LC
authorizedShippingLinesShipping lines explicitly permitted under the LC
restrictedShippingLinesShipping lines explicitly prohibited under the LC

LC and operations

An LC is typically attached to an export sale operation. The LC covers the payment obligation for that shipment — the customer's bank commits to paying once the seller presents the required documents (BL, invoice, packing list, etc.) within the periodPresentation window.

AI verification for LCs

When the aiApi field on the linked PdfTemplate is set to LC_VERIFICATION, Jules can use AI to verify an uploaded LC document against the terms recorded in Jules — checking that the bank-issued document matches what was agreed. Discrepancies are surfaced as Mismatch records (see AI Document Verification).


Email Integration

Jules has a built-in email integration that allows users to send commercial documents directly from the platform. Sent emails are stored as Email records linked to their parent entity.

Sending an email

The sendEmail mutation accepts:

FieldDescription
toRecipients (email + optional display name)
ccCC recipients
bccBCC recipients
fromSender address (must be an authorized sending address)
subjectEmail subject line
bodyEmail body (HTML supported)
linkedEntityThe entity type the email is associated with
linkedEntityIdsThe specific entity IDs (can be multiple, e.g., multiple containers)
pdfIdsJules PDF records to attach to the email
fileIdsAdditional file IDs (non-PDF attachments)
tokenAuthentication token for the sending integration
threadIdID of an existing email thread to reply into

Email storage

Each sent email is stored as an Email record with:

  • Full header information (to, from, cc, bcc)

  • Subject and body

  • Links to the attached Pdf records

  • Reference to the linked Jules entity

Emails are queryable via filteredEmails filtered by linkedEntity + linkedEntityIds, allowing the activity feed of an operation or invoice to display the full communication history.

Permission model

The EMAILS resource is governed by Permit.io:

  • SEND — controlled at the linked entity level (users can only send from entities they have access to)

  • VIEW — can view sent emails for accessible entities


Webhook System

Jules provides a webhook system that automates the distribution of data and documents to external recipients when specific events occur. Webhooks are pre-configured notification channels, typically used to:

  • Share operation summaries with counterparties or internal stakeholders

  • Notify logistics partners when containers are ready to ship

  • Push shipment data to external systems

  • Share invoices with finance teams

Webhook triggers

TriggerWhen it fires
ON_SHARE_OPERATIONWhen an operation is shared with a counterparty
ON_SHARE_CONTAINERSWhen container data is shared
ON_SHARE_SHIPMENTSWhen a shipment summary is shared
ON_SHARE_OFFERWhen an offer is shared externally
ON_SHARE_INVOICEWhen an invoice is shared
ON_SHARE_BOOKINGSWhen freight booking data is shared

Webhook fields

FieldDescription
triggerThe event that activates this webhook
mediumDelivery channel — EXTERNAL for outbound webhooks
valueThe webhook endpoint or destination
titleHuman-readable name for the webhook configuration
templateIdID of the message template used to format the payload
templateStringRaw template string (alternative to templateId)
toContact records who receive this webhook
receipientsRaw email/contact list
ccCC recipients
disableAutoCCWhether to suppress automatic CC behavior
dateOfLastSentTimestamp of the last successful dispatch

Running a webhook manually

In addition to automatic triggers, users can manually fire a webhook for an operation using runOperationWebhook:

runOperationWebhook(operationId, webhookId, type)

This is useful for re-sending a notification, or sending to a new recipient who joined after the original send.

Associating webhooks with operations

The upsertWebhookToOperation mutation creates a persistent link between a webhook configuration and an operation, so that future events on the operation automatically use the configured webhook.

External webhook choices

Before sending, Jules builds a filtered list of applicable webhook configurations for the user via externalWebhookChoices. This query:

  1. Fetches all EXTERNAL webhooks matching the trigger type

  2. Enriches them with entity-specific data (e.g., container details for ON_SHARE_CONTAINERS)

  3. Returns a dropdown-ready list with pre-populated recipient suggestions


Relationships with Other Modules

The document and integration layer connects to virtually every other Jules module:

ModuleRelationship to documents
OperationSource of PO and SO documents; poStatus / soStatus track document progress
InvoiceSource of customer and supplier invoice PDFs
ContainerSource of delivery slips, load reports, Annex 7
Freight BookingSource of booking confirmation documents
ShipmentSource of shipment-level documents
Letter of CreditCarries LC details; LC document can be verified with AI
EmailDistribution channel for generated documents
WebhookAutomated distribution to external systems and contacts
PdfTemplateConfiguration that drives document rendering
DocTermLegal clauses embedded in generated documents
Site / QualityDefault parameters pre-filled into document generation dialogs
DocReceivablesDefines which documents are expected from a counterparty
PortalDocuments can be shared on the counterparty portal via sharedOnPortal

Key Business Rules

1. Template selection priority

When multiple templates exist for the same docType + linkedEntity combination, Jules uses the priorityConfig field to determine which template to use. The isDefault flag marks the fallback template for cases where no priority rule matches.

2. Signed document upload auto-updates operation status

When a user uploads a signed PO back into Jules (savePdfInfo with docType: PURCHASE_ORDER), Jules automatically advances the operation's poStatus to SIGNED_AND_UPLOADED. The same applies for SALES_ORDERsoStatus. This keeps the document lifecycle in sync with the operation status without manual updates.

3. Documents notify via worker queue

All document upload events (manual uploads, approval requests, approval decisions) fire asynchronous notifications through the RabbitMQ worker queue. This means document-related notifications (e.g., "Your document has been approved") are delivered without blocking the API response.

4. AI verification is non-destructive

Mismatch records produced by AI verification are proposals, not automatic corrections. A human reviewer must explicitly approve or reject each mismatch. Jules never auto-corrects data based on AI output — the AI highlights discrepancies, the user decides.

5. Webhooks respect operation type

When running runOperationWebhook, the type parameter (BUY or SELL) controls which version of the data is sent. This is important because an allocation links a purchase and a sale — the webhook must know which side to represent to the external recipient.

6. Email threads are preserved

Emails sent from Jules can be associated with an existing threadId, allowing replies to be grouped in the email client. This is important when multiple emails are sent about the same shipment — they appear as a conversation thread, not isolated messages.

7. Public templates are accessible to portal users

Templates flagged isPublic: true are accessible to external counterparty users on the Jules portal. This allows, for example, a supplier to download their delivery slip directly from the portal, without needing a full Jules account.

8. Letter of Credit shipping line restrictions are enforced at the booking stage

The authorizedShippingLines and restrictedShippingLines fields on an LC carry commercial restrictions from the buyer's bank. Operations teams use these to ensure the freight booking uses a compliant carrier, since using a restricted shipping line could result in the bank refusing to honor the LC.

9. PDF merging preserves document order

When using mergePdfs, Jules strictly respects the order of ids provided. The final merged document presents pages in the exact sequence requested — typically: BL first, then packing list, then invoice, etc. — matching the order required by the bank for LC presentation.

10. DocReceivables vs uploaded PDFs

DocReceivables tracks what documents are expected from a counterparty. Actual received documents are stored as isUploaded: true PDF records. Together, these two tables power the "documents pending" checklist visible on an operation — showing what has been received and what is still outstanding.


Glossary

TermDefinition
Advising bankThe seller's bank that transmits the LC and advises the beneficiary of its terms
AI verificationAutomated comparison of an uploaded document against Jules data using an AI extraction service
Annex 7EU regulatory document required for cross-border shipments of waste materials
Confirming bankAn additional bank that adds its own payment guarantee to an LC, reducing the beneficiary's risk
DocReceivablesConfiguration table defining which documents are expected from a counterparty
DocTermA legal clause or standard term embedded in generated commercial documents
DocTypeThe category of a document (PO, SO, Invoice, BL, etc.)
Issuing bankThe buyer's bank that issues the Letter of Credit
LC (Letter of Credit)A bank-issued instrument guaranteeing payment to the seller upon presentation of compliant shipping documents
LinkedEntityThe Jules entity type (operation, invoice, container, etc.) that a document is attached to
MismatchA discrepancy detected by AI between a document's content and Jules data
PdfA document record in Jules — either generated by the system or manually uploaded
PdfArgsThe pre-filled data payload used to render a document from a template
PdfTemplateA reusable configuration defining how a document type is rendered
Period of presentationThe number of days after shipment within which documents must be presented to the bank under an LC
PO (Purchase Order)Document sent to a supplier confirming the terms of a purchase
poStatus / soStatusLifecycle status of the PO or SO document: PENDING → CREATED → SENT → SIGNED_AND_UPLOADED
ReviewStatusThe outcome of a document approval workflow: PENDING, APPROVED, or REJECTED
SO (Sales Order)Document sent to a customer confirming the terms of a sale
VerificationStatusThe progress of a document verification process: PENDING, IN_PROGRESS, or COMPLETED
WebhookA pre-configured notification channel that dispatches data to external recipients when a trigger event fires
WebhookToOperationA persistent link associating a webhook configuration with a specific operation