Proof

Definition

A Proof is a document that supports a financing request: the invoice itself, a signed CMR, a delivery note, a timesheet, a purchase order.

A Proof carries one file and a type taken from a closed list. It has its own id, and it is linked to one or several targets: an Invoice, a Receivable, a Credit memo or a Loan.

Until now, documents were sent through the attachments field of each object, with no type attached to them. With Proofs, a file is uploaded once, typed, and then linked to every object it supports.

📘

attachments still works on every object. See the Migrating from attachments section below.

Creating a Proof

Creating a Proof takes two calls:

  1. Upload the file with POST /companies/{companyId}/upload, which returns a fileId. This is also how you send a structured record, as a .json file.
  2. Create the Proof with its type and its fileId. Pass targets in the same call to link it right away, or omit them and link the Proof afterwards.

The file of a Proof never changes. To replace a document, create a new Proof and archive the old one, so the history of the object stays complete.

Linking Proofs when creating an object

An Invoice, a Receivable or a Loan can take its Proofs at creation, through proofIds:

  1. Upload each file with POST /companies/{companyId}/upload.
  2. Create each Proof with POST /companies/{companyId}/proofs, with no targets.
  3. Create the object and pass the Proof ids in proofIds, up to 20 per call.

The Proofs are linked inside the same call, so they count toward the evidence the object requires at creation. A Proof already linked to another object can be named again: one supplier contract can support several Invoices.

proofIds follows the same rules as a link. Each Proof must belong to your company, must not be archived, and must carry a type the object accepts. Sending the same call twice links each Proof once.

proofIds is accepted on creation only. Once the object exists, use POST /companies/{companyId}/proofs/{proofId}/link. A Credit memo takes no proofIds.

🚧

Send the evidence of an object as proofIds or as attachments, not both. A body that carries both is refused with 400 CONFLICTING_EVIDENCE_CARRIERS.

Proof types

Each type is accepted on specific targets. A Proof linked to a target that does not accept its type will get an API validation error with INVALID_PROOF_TYPE.

TypeAccepted onNotes
INVOICEInvoiceThe invoice document itself.
DISBURSEMENT_NOTEInvoiceStands in for the invoice document.
ADDITIONAL_INVOICEInvoice, LoanA second invoice document supporting the same claim.
INVOICE_BREAKDOWNInvoice, LoanThe lines of the invoice, each with its amount. Sent as a .json file. Any valid JSON is accepted for now.
CMRInvoice, LoanCovers a scanned paper CMR and an e-CMR alike.
TRANSPORT_ORDERInvoice
DELIVERY_NOTEInvoice
TIMESHEETInvoice, Loan
INVOICE_VALIDATIONInvoiceThe debtor validated the invoice. Sent as a .json file.
INVOICE_DELIVERYInvoiceYou sent the invoice to the debtor. Sent as a .json file.
PURCHASE_ORDERReceivable
PROFORMA_INVOICEReceivable
TRANSACTION_PROOFReceivable
PAYMENT_PROOFReceivable
SUPPLIER_CONTRACTInvoice, ReceivableThe commercial contract with the supplier.
CREDIT_MEMOCredit memo
OTHERAll fourRequires a label describing the document. Optional on the other types.

UNKNOWN also exists, but it is reserved for documents migrated from attachments. You cannot create a Proof with that type.

📘

Loan or Invoice

A Loan accepts CMR, ADDITIONAL_INVOICE, INVOICE_BREAKDOWN, TIMESHEET and OTHER. The Invoice accepts these types too, so you can link these documents to either one.

Link a document to the Loan when it supports the specific amount that this Loan requests on the invoice. For example, an INVOICE_BREAKDOWN that shows the invoice lines this Loan finances. It helps us decide on that amount. A document that supports the invoice as a whole goes on the Invoice.

Source

source tells whose record a Proof is. Aria sets it and you cannot change it.

  • COMPANY: everything that comes from you, through the API or through the dashboard, including documents our teams upload on your behalf.
  • ARIA: records produced by our own systems, for instance an invoice validation collected through the Aria widget. You never create them, and they never appear in attachments. Read them through the proof endpoints.

Linking a Proof to several targets

One Proof can support several objects. A supplier contract is created once and linked to every Invoice it covers, instead of being uploaded again for each one.

  • POST /companies/{companyId}/proofs/{proofId}/link adds targets.
  • POST /companies/{companyId}/proofs/{proofId}/unlink removes targets, and keeps the Proof.

Both calls take a list of targets, so one call can link a Proof to several objects at once. Both are idempotent: a target already in the requested state is ignored.

A Proof can only be linked to the targets its own type accepts, so a DELIVERY_NOTE can go on an Invoice but not on the Loan that finances it, while a CMR can go on both.

Adding a Proof, or linking it to one more target, is never blocked by the status of a Loan. Linking the same file twice to the same target is refused with DUPLICATE_PROOF.

To list the Proofs of one object, filter GET /companies/{companyId}/proofs on targetId, alone or with targetType: filter=and(eq(targetType,Invoice),eq(targetId,<invoiceId>)). Both filters match the same link. They are accepted at the top level or under and, and refused under or.

Archiving a Proof

DELETE /companies/{companyId}/proofs/{proofId} archives a Proof. It never deletes it, and it never drops its links.

An archived Proof keeps its targets, so the full history of an Invoice or of a Receivable stays available: list the proofs of that object with includeArchived=true. A list call without that parameter returns the active proofs only.

Required proofs

An Invoice and a Receivable must carry evidence at creation. The rule applies to every client.

ObjectWhat it must carry at creation
InvoiceAt least one INVOICE or DISBURSEMENT_NOTE proof.
ReceivableAt least one proof of any type accepted on a Receivable.
LoanNothing. A Loan is never refused for missing evidence.
Credit memoNothing.

Proofs sent through proofIds and files sent through attachments both count. A creation that does not satisfy the rule is refused with 422 PROOF_REQUIRED, and no object is created.

When a Proof can be removed

Archiving a Proof, or unlinking it from a target, follows the same rule as editing the object itself:

  • Every Loan linked to the target must be in CREATED status. Any other status refuses the call with 409 PROOF_LOCKED.
  • The target must keep the evidence it required at creation. Removing the last one is refused with 409 PROOF_REQUIRED. Create the replacement first, then archive the old Proof.

Adding evidence is always allowed, whatever the status of the Loans.

Migrating from attachments

attachments is deprecated on the Invoice, the Receivable, the Loan and the Credit memo. It keeps working, and no integration breaks.

  • What you send in attachments becomes a Proof: INVOICE on an Invoice, CREDIT_MEMO on a Credit memo, and UNKNOWN on a Receivable or a Loan.
  • Reading attachments returns the active proofs of your own company linked to that object. Proofs that Aria produced carry source: ARIA and stay out of that list.
  • A PATCH keeps its current behavior: the list you send replaces the list that was there. A new file becomes a new Proof, and a file you drop is archived rather than deleted. A dropped file that is also linked to another object is only unlinked from this one.
  • A PATCH that does not carry attachments changes nothing.

Moving to Proofs tells us what each document is, which is what lets our checks run on them rather than having someone open every file.

Webhook payload

Four events are sent: proof.created, proof.archived, proof.linked and proof.unlinked. Subscribe to them through POST /companies/{companyId}/subscriptions/webhook, as for any other event. A Proof named in proofIds sends proof.linked when the object is created.

{
    "date": Date,
    "event": "proof.created",
    "payload": {
        id: string,
        fileId: string | null,
        legacyUrl: string | null,
        type: string,
        label: string | null,
        source: "COMPANY" | "ARIA",
        targets: Array<{ type: "Invoice" | "Receivable" | "CreditMemo" | "Loan", id: string }>,
        createdAt: string,
        updatedAt: string,
        archivedAt: string | null
    }
}

legacyUrl is filled only for a Proof built from a document sent before Proofs existed. Every Proof you create carries a fileId.

When the document is stored by Aria, the legacyUrl returned by the proof endpoints expires 5 minutes after the response. Read the Proof again to get a fresh URL rather than storing it.

Errors

CodeStatusMeaning
PROOF_REQUIRED422 at creation, 409 on an archive or an unlinkRequired evidence is missing, or the call would remove the last one.
PROOF_LOCKED409A Loan on the target is in a status that locks its proofs. Adding is never locked.
INVALID_PROOF_TYPE422The type is not accepted on that target.
INVALID_PROOF_FILE422The fileId does not exist or belongs to another company: upload the file through POST /companies/{companyId}/upload first. Or the type expects a .json file and its content does not match the schema. An INVOICE_BREAKDOWN only needs to be valid JSON.
DUPLICATE_PROOF409The same fileId is already linked to that target.
CONFLICTING_EVIDENCE_CARRIERS400A creation body carries both attachments and proofIds.

Rules

  • A Proof carries exactly one file, and that file never changes.
  • A Proof belongs to your company, not to a target. It keeps its id across every target it is linked to.
  • A Proof can be linked to several targets, and it can be linked to none.
  • label is required on OTHER and optional on every other type.
  • An archived Proof takes no new link, and it stays visible with includeArchived=true.
  • An Invoice can carry more than one INVOICE proof, which is what makes replacing a document possible.

Did this page help you?