Viacle API
Viacle is the commercial purchase intelligence layer between payment confirmation and ERP entry. It transforms ACH wires, commercial card transactions, freight invoices, and vendor bills into GL-coded, commodity-classified purchase objects — consistent schema, regardless of payment rail or source.
https://api.viacle.io/api/v1
All responses are JSON. All requests must include an Authorization: Bearer header.
The interactive version of these docs — with live code samples, a sidebar navigator, and a schema explorer — is at
viacle.io/docs.
Authentication
All API requests require a Bearer token in the Authorization header.
Authorization: Bearer vi_live_sk_your_api_key
vi_live_sk_ — production |
vi_test_sk_ — sandbox (deterministic test objects, no real documents processed)
Key Security
| Property | Behaviour |
|---|---|
| Storage | SHA-256 hash only. The raw key is returned once at creation and never persisted in plaintext. |
| Revocation | Immediate — revoked keys are rejected on the next request. |
| Rotation | POST /api/keys/create to issue a new key, POST /api/keys/:id/revoke to invalidate the old one. |
| Introspection | GET /api/v1/keys/self/permissions returns effective scopes for the calling key. |
Quickstart
One API call turns a vendor invoice, card transaction, or freight bill into a structured purchase object with GL code, vendor TIN, and line-item commodity codes. Get from zero to your first purchase object in under five minutes.
Step 1 — Create a purchase from an invoice URL
curl -X POST https://api.viacle.io/api/v1/purchases \
-H "Authorization: Bearer vi_live_sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"document_url": "https://example.com/invoice.pdf",
"reference_id": "AP-2026-00831"
}'
Step 2 — Receive the purchase object
{
"id": "pur_vc_82af31",
"object": "purchase",
"status": "completed",
"merchant": {
"name": "Grainger Industrial Supply",
"id": "mer_grngr",
"category": "Industrial Supplies",
"tin": "36-1165231",
"registered_name": "W.W. Grainger, Inc."
},
"purchase_date": "2026-03-20",
"amounts": { "subtotal": 2847.00, "tax": 227.76, "total": 3074.76, "currency": "USD" },
"items": [
{
"name": "3M Nitrile Gloves CS",
"quantity": 2,
"price": 296.00,
"sku": "GRW-7105-0232",
"commodity_code": "46181500",
"category": "Safety & PPE"
},
{
"name": "Honeywell Respirator Half-Face",
"quantity": 1,
"price": 589.00,
"sku": "GRW-8250-4120",
"commodity_code": "46182001",
"category": "Safety & PPE"
}
],
"expense": {
"gl_code": "6400",
"cost_center": "OPS-WEST",
"approval_status": "pending_review"
},
"reportable_1099": false,
"data_source": "ocr_extracted",
"reference_id": "AP-2026-00831",
"confidence": { "merchant": 0.99, "items": 0.94, "gl_code": 0.91 },
"verification_url": "https://api.viacle.io/verify/pur_vc_82af31"
}
Step 3 — Retrieve it any time
curl https://api.viacle.io/api/v1/purchases/pur_vc_82af31 \
-H "Authorization: Bearer vi_live_sk_your_api_key"
Rate Limits
| Endpoint group | Default limit | Response on exceeded |
|---|---|---|
| Read endpoints (GET) | 200 req / min | 429 RATE_LIMIT_EXCEEDED |
| POST /purchases | 30 req / min | 429 RATE_LIMIT_EXCEEDED |
| Batch endpoints | 5 req / min | 429 RATE_LIMIT_EXCEEDED |
The Retry-After header on a 429 response indicates when the window resets. Enterprise plans carry higher or custom limits — contact the Viacle team to discuss volume requirements.
Error Codes
All errors follow a consistent envelope: { "error_code": "...", "message": "...", "trace_id": "..." }.
| HTTP status | error_code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Request body failed schema validation. The message field identifies the failing field. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 403 | FORBIDDEN | Key is valid but lacks the required scope for this endpoint. |
| 404 | NOT_FOUND | Purchase, entity, or resource does not exist under your account. |
| 409 | CONFLICT | Duplicate reference_id — a purchase with this reference already exists. Safe to retry with the same Idempotency-Key. |
| 422 | NO_TRANSACTIONS_FOUND | Document was processed but no extractable purchase data was found. |
| 429 | RATE_LIMIT_EXCEEDED | Request rate exceeded. Retry after the window indicated by Retry-After. |
| 500 | INTERNAL_SERVER_ERROR | Unexpected server error. Automatically captured and alerted. Include the trace_id when contacting support. |
The Purchase Object
Every purchase processed by Viacle becomes a persistent, programmable object. The schema is deterministic: every top-level field is always present, even when the value is null. The full annotated schema with lifecycle diffs and webhook event payloads is at viacle.io/object.
stringrequired
pur_vc_ followed by alphanumeric characters.string
"purchase".stringrequired
pending, processing, completed, failed, reversed, refunded.objectrequired
id, name, category, region, tin (EIN, caller-provided — never inferred), lei (ISO 17442 Legal Entity Identifier), registered_name, registered_entity_type, registration_status, formation_date, website, logo_url.stringrequired
objectrequired
subtotal, tax, total, currency. Currency accepts ISO 4217 fiat codes (USD, EUR, GBP) or crypto identifiers (BTC, ETH, USDC).arrayrequired
name, quantity, price, sku, upc, brand, category, commodity_code (UNSPSC), manufacturer, is_alcohol, is_tobacco. Empty array when no line items are extractable.object
gl_code, cost_center, department, project_code, approval_status (pending_review | approved | rejected | reimbursed), approved_by, approved_at.object
type (card, ach, wire, check, crypto, fleet), last_four, bin. Full card numbers are never accepted or stored.stringrequired
merchant_push (audit-grade), e_invoice (PEPPOL/EDI mandate — equivalent trust), ocr_extracted (PDF/image extraction), enriched (transaction-level only, no line items). Used by AP teams and AI agents to assess evidence weight.objectrequired
merchant, items, gl_code. Includes a detail sub-object with scores for individual fields. Fields below 0.5 should be treated as provisional.booleanrequired
GET /entities/:id/tax-summary.string
GET /purchases?reference_id= to look up by your reference.string
object
pro_number, bill_of_lading, carrier_scac, mode, origin, destination, base_freight_amount, fuel_surcharge_amount, pod_confirmed. Populated by the EDI 210/214 and freight-platform connectors.stringrequired
integerrequired
Create Purchase POST /purchases
Create a purchase object from a document URL, structured transaction metadata, or raw text. Returns the complete purchase object synchronously for most requests; large PDFs trigger an async extraction job and return status: "processing".
// From a document URL
{
"document_url": "https://your-domain.com/invoices/INV-2026-0041.pdf",
"reference_id": "AP-2026-00831",
"entity_id": "ent_acme_corp"
}
// From structured transaction metadata
{
"merchant_name": "WEX Fleet Services",
"total": 1847.30,
"currency": "USD",
"purchase_date": "2026-03-20",
"payment_method": { "type": "fleet", "last_four": "4421" },
"reference_id": "TXN-88321"
}
// AP invoice ingest (alternate endpoint — see below)
POST /purchases/ingest
{
"vendor_name": "Turner Mechanical LLC",
"invoice_number":"INV-TM-0441",
"po_number": "PO-2026-0814",
"line_items": [
{ "description": "HVAC Ductwork Zone B", "amount": 18400.00, "quantity": 1 }
],
"total": 18400.00,
"currency": "USD"
}
| Field | Type | Description |
|---|---|---|
| document_url | string | Publicly accessible PDF or image URL. Viacle fetches and extracts line items, merchant, and amounts. |
| raw_text | string | Plain-text invoice content (EDI, XML, CSV). Mutually exclusive with document_url. |
| merchant_name | string | Vendor name. Used when submitting structured transaction data rather than a document. |
| total | number | Transaction total in major currency units (e.g. 1847.30 for $1,847.30). |
| currency | string | ISO 4217 currency code. Defaults to USD. |
| purchase_date | string | ISO 8601 date (YYYY-MM-DD). |
| reference_id | string | Your AP reference number, PO number, or transaction ID. Stored and indexed. |
| entity_id | string | Entity to link this purchase to for aggregation and spend analytics. |
| line_items | array | Pre-structured line items. Each item: description, amount, quantity, sku, commodity_code. |
AP Invoice Ingest POST /purchases/ingest
AP-workflow-focused alternative to POST /purchases. Accepts vendor name, line items, PO reference, and payment terms using vocabulary AP teams already use. Returns the normalized purchase object with a commercial block and an ingest_summary envelope covering GL assignment, match status, and data completeness.
/purchases/ingest when you have structured AP data (vendor name, invoice number, PO reference, line items) and want the response shaped for an AP workflow. Use POST /purchases for document URL extraction or raw transaction enrichment.
Get Purchase GET /purchases/:id
curl https://api.viacle.io/api/v1/purchases/pur_vc_82af31 \
-H "Authorization: Bearer vi_live_sk_your_api_key"
Returns the full purchase object. Also accepts GET /purchases?reference_id=AP-2026-00831 to look up by your reference ID.
List Purchases GET /purchases
Returns a paginated list of purchases. Query parameters:
| Parameter | Type | Description |
|---|---|---|
| reference_id | string | Exact match on your reference ID. |
| entity_id | string | Filter by entity. |
| since | integer | Unix timestamp. Returns purchases created after this time. |
| until | integer | Unix timestamp. Returns purchases created before this time. |
| status | string | Filter by purchase status. |
| rail_source | string | Filter by payment rail: card, ach, wire, freight, edi, crypto, fleet, check. |
| locale | string | Filter by BCP 47 locale (e.g. en-US, de-DE). |
| limit | integer | Results per page. Default 25, max 100. |
| offset | integer | Pagination offset. |
Update Purchase PATCH /purchases/:id
Update mutable fields on an existing purchase object. Commonly used to set or update GL codes, approval status, and cost center after creation.
{
"expense": {
"gl_code": "6400",
"cost_center": "OPS-WEST",
"approval_status": "approved",
"approved_by": "jane.doe@company.com"
}
}
Patchable fields: merchant_name, purchase_date, total, items, expense (entire block), entity_id, reference_id, locale, receipt_medium. Patching emits a purchase.updated webhook event.
Delete Purchase DELETE /purchases/:id
Soft-deletes a purchase record. The object is removed from all list and query endpoints immediately. Per-key data retention policy determines when the record is permanently purged. Requires the purchases:write scope.
Complete Endpoint Reference
This inventory is generated directly from /openapi.json. It contains 178 documented operations across 142 paths. The machine-readable contract is authoritative for methods, request schemas, response codes, and required scopes.
Generated Schemas
These component schemas are rendered from the same OpenAPI contract as the endpoint inventory. Narrative guidance above explains common workflows; this section is the authoritative field reference.
CommercialCase
stringrequired
stringrequired
stringrequired
stringrequired
stringrequired
stringrequired
PortablePurchaseMoney
string
stringrequired
stringrequired
CommercialCaseObject
stringrequired
stringrequired
stringrequired
string
stringrequired
string
string
string
available | restricted | purgedrequired
string
string
stringrequired
CommercialCaseAssertion
stringrequired
stringrequired
string
stringrequired
unknownrequired
boolean
stringrequired
stringrequired
stringrequired
number
string
string
string
string
stringrequired
CommercialCaseLink
stringrequired
stringrequired
stringrequired
stringrequired
stringrequired
number
string
string
string
stringrequired
CommercialCaseAllocation
stringrequired
stringrequired
stringrequired
PortablePurchaseMoneyrequired
stringrequired
stringrequired
string
string
string
stringrequired
CommercialCaseDecision
stringrequired
stringrequired
authoritative | attested | observed | inferred | user_confirmed | policyrequired
stringrequired
stringrequired
CommercialCaseDetail
CommercialCaserequired
array<CommercialCaseObject>required
array<CommercialCaseAssertion>required
array<CommercialCaseLink>required
array<CommercialCaseAllocation>required
array<CommercialCaseDecision>required
CommercialCasePage
array<CommercialCase>required
unknownrequired
CommercialCaseProjection
stringrequired
stringrequired
stringrequired
integerrequired
string
CommercialCaseObjectList
array<CommercialCaseObject>required
CommercialCaseAssertionList
array<CommercialCaseAssertion>required
CommercialCaseLinkList
array<CommercialCaseLink>required
CommercialCaseAllocationList
array<CommercialCaseAllocation>required
CommercialCaseDecisionList
array<CommercialCaseDecision>required
CommercialCasePublicAssertionValue
unknown
CommercialCaseConflict
stringrequired
unknownrequired
array<object>required
CommercialCaseConflictList
array<CommercialCaseConflict>required
CommercialCaseTimelineEvent
unknown
CommercialCaseTimeline
array<CommercialCaseTimelineEvent>required
CommercialCaseDecisionRequest
confirm_link | reject_link | adjust_allocation | approve | hold | dispute | request_evidence | mark_evidence_insufficient | resolve | reopenrequired
string
object
object
string
stringrequired
string
string
number
string
adjust | reverse
CommercialCaseBankingContext
unknownrequired
unknownrequired
stringrequired
stringrequired
stringrequired
objectrequired
array<object>required
array<CommercialCaseAllocation>required
array<object>required
integerrequired
array<object>required
UnsupportedPprVersion
unknownrequired
stringrequired
stringrequired
array<unknown>required
AirwallexDeliveryRequest
stringrequired
stringrequired
stringrequired
payment_intent | transferrequired
stringrequired
AirwallexDeliveryConfigurationCreate
stringrequired
unknownrequired
boolean
array<payment_intent | transfer | payment_intent_reference | transfer_reference>
array<string>
AirwallexDeliveryConfigurationUpdate
boolean
array<payment_intent | transfer | payment_intent_reference | transfer_reference>
array<string>
AirwallexDeliveryConfiguration
stringrequired
stringrequired
unknownrequired
booleanrequired
configured_unvalidated | validated | invalidrequired
string
string
array<string>required
array<string>required
stringrequired
AirwallexSuccessorRequest
stringrequired
AirwallexDelivery
stringrequired
stringrequired
payment_intent | transferrequired
stringrequired
string
string
string
stringrequired
ConsumerCommercialCaseGrantRequest
stringrequired
string
string
stringrequired
string
ConsumerCommercialCaseGrant
stringrequired
unknown
array<string>required
stringrequired
stringrequired
unknownrequired
unknownrequired
stringrequired
ConsumerCommercialCaseGrantEnvelope
ConsumerCommercialCaseGrantrequired
ConsumerCommercialCaseGrantList
array<ConsumerCommercialCaseGrant>required
Error
stringrequired
stringrequired
LineItem
stringrequired
numberrequired
number
string
string
string
string
boolean
CreatePurchase
numberrequired
stringrequired
string
transfer | payment | refund | deposit | withdrawal | purchase | auth | pre_auth | capture | void
stringrequired
stringrequired
pending | processing | completed | failed | reversed | refundedrequired
string
array<LineItem>
number
number
string
card_transaction | receipt | invoice | email_confirmation | api_submission | mileage_claim | per_diem_claim | mobile_capture | wallet_payment
string
string
string
string
fednow | sepa_instant | upi | swift | iso20022 | camt052 | camt053 | camt054 | mt940 | mt942 | bai2 | stripe | coinbase_commerce | hedera | x402 | ach | rtp | wire | card | primer | stables | cybrid | rainforest | pingpong | thunes_accept | thunes_mt | adyen | mollie | rapyd | pix | mercado_pago | checkout | klarna | stone | pagseguro | boleto | xmoney_crypto | knot | truelayer | ebizcharge | maxio | orb | chargebee | recurly | paddle | nmi | paystand | authorize_net | edi204 | edi210 | edi211 | edi214 | edi_855_ack | edi_856_asn | edi_997_ack | mcleod | mercurygate | turvo | relay_payments | cass | loop | sila | brasilpays | derivative_path | moonpay | roadsync | fleet_check | wex_fleet | fleetcor | ups | fedex | dhl_express | tforce_freight | trimble | sap_tm | magnus_tms | blue_yonder | estes_express | saia | rl_carriers | arcbest | odfl | alvys_tms | rose_rocket | samsara_eld | motive_eld | edi_820_remittance | edi_990_response | edi_824_advice | checkalt | project44 | flexport | bank_feed | carrier_invoice_manual | freight_hero | freight_ops_platform | lojistic | shipwell | cybersource | xero | other
number
string
string
string
string
object
Purchase
string
purchase
number
string
object
array<LineItem>
string
string
string
object
object
object
object
array<PostDeliveryLifecycleEvent>
string
string
PurchaseList
array<Purchase>
boolean
string
integer
Entity
string
entity
array<object>
string
string
string
string
string
EntityList
array<Entity>
boolean
CreateEntity
array<object>
string
string
string
string
Policy
string
expense_policy
string
amount_limit | merchant_blocklist | category_blocklist | require_memo | require_gl_code
string
boolean
string
CreatePolicy
stringrequired
amount_limit | merchant_blocklist | category_blocklist | require_memo | require_gl_coderequired
stringrequired
boolean
ReturnEligibility
return_eligibility
string
boolean
integer
string
integer
string
number
string
string
object
ReceiptLink
receipt_link
string
string
string
string
string
ExpenseSummaryItem
string
number
integer
ApprovalAuditEntry
string
string
purchase.approval_approved | purchase.approval_rejected | purchase.approval_reimbursed
string
object
string
CreateWidgetSession
string
string
dark | light
string
string
string
boolean
WidgetSession
string
string
integer
string
string
WidgetSessionVerify
boolean
string
string
dark | light
PurchaseLifecycleEvent
string
string
object
string
PostDeliveryLifecycleEvent
stringrequired
purchase_lifecycle_eventrequired
stringrequired
warranty_activated | warranty_expired | return_window_opened | return_window_closed | subscription_renewal | asset_depreciation_posted | audit_referenced | payment_dispute_opened | payment_dispute_resolved | asset_receivedrequired
objectrequired
string
stringrequired
CreatePostDeliveryLifecycleEvent
warranty_activated | warranty_expired | return_window_opened | return_window_closed | subscription_renewal | asset_depreciation_posted | audit_referenced | payment_dispute_opened | payment_dispute_resolvedrequired
object
string
string
PostDeliveryLifecycleEventList
array<PostDeliveryLifecycleEvent>required
falserequired
ApRule
stringrequired
ap_auto_rulerequired
stringrequired
integerrequired
ApRuleConditionsrequired
auto_approve | route_torequired
stringrequired
booleanrequired
stringrequired
ApRuleConditions
number
number
number
none
boolean
boolean
boolean
string
CreateApRule
stringrequired
integer
ApRuleConditionsrequired
auto_approve | route_torequired
string
boolean
UpdateApRule
string
integer
ApRuleConditions
auto_approve | route_to
string
boolean
ApEvaluation
ap_evaluationrequired
stringrequired
auto_approve | route_to | no_rulerequired
stringrequired
stringrequired
stringrequired
numberrequired
array<string>required
booleanrequired
stringrequired
stringrequired
PurchaseSplit
string
string
string
string
number
number
string
string
PurchaseSplitsResponse
purchase_splits
string
integer
array<PurchaseSplit>
CreateSplitsBody
array<object>required
JournalEntryDraft
journal_entry_draftrequired
stringrequired
stringrequired
draft | posting | postedrequired
stringrequired
stringrequired
numberrequired
stringrequired
stringrequired
stringrequired
numberrequired
numberrequired
stringrequired
stringrequired
boolean
string
string
stringrequired
stringrequired
CloseReadinessBreakdown
integerrequired
integerrequired
integerrequired
integerrequired
integerrequired
CloseReadinessException
stringrequired
array<gl_code | cost_center | duplicate_flag | fraud_flag | pending_status>required
CloseReadinessBenchmark
excellent | strong | improving | developing | earlyrequired
stringrequired
ReceiptComplianceSummary
receipt_compliance_summaryrequired
entity_id | department | cost_centerrequired
stringrequired
stringrequired
numberrequired
integerrequired
integerrequired
integerrequired
array<ReceiptComplianceGroup>required
integerrequired
ReceiptComplianceGroup
stringrequired
integerrequired
integerrequired
integerrequired
numberrequired
SpendingByTagSummary
spending_by_tagrequired
stringrequired
stringrequired
integerrequired
array<SpendingTag>required
integerrequired
SpendingTag
stringrequired
numberrequired
integerrequired
array<string>required
PaymentRailsSummary
payment_rails_breakdownrequired
stringrequired
stringrequired
stringrequired
integerrequired
array<PaymentRailBreakdown>required
integerrequired
PaymentRailBreakdown
stringrequired
integerrequired
numberrequired
numberrequired
VendorConcentrationSummary
vendor_concentration_summaryrequired
stringrequired
stringrequired
stringrequired
integerrequired
array<VendorConcentration>required
integerrequired
VendorConcentration
stringrequired
stringrequired
numberrequired
integerrequired
numberrequired
ReconciliationItem
stringrequired
stringrequired
numberrequired
stringrequired
stringrequired
stringrequired
string
number
array<string>
ReconciliationStats
integerrequired
integerrequired
integerrequired
integerrequired
Dispute
string
string
string
string
string
number
freight | billing
open | pending_correction | resolved | rejected | withdrawn
string
string
integer
integer
integer
CreateDisputeBody
stringrequired
number
weight_discrepancy | unauthorized_accessorial | rate_mismatch | duplicate_billing | late_delivery | missing_pod | class_reclassification | routing_violation | fuel_surcharge_discrepancy | detention_overcharge | damage_claim | shortage
string
UpdateDisputeBody
pending_correction | resolved | rejected | withdrawn
string
string
CommercialEventIngest
string
objectrequired
objectrequired
CommercialEventRelationshipDecision
confirm | rejectrequired
string
CommercialEventRelationshipProposal
stringrequired
stringrequired
numberrequired
stringrequired
stringrequired
string
string
object
CommercialEventRelationship
unknownrequired
stringrequired
stringrequired
stringrequired
proposed | ambiguous | confirmed | rejected | supersededrequired
numberrequired
stringrequired
array<string>required
objectrequired
stringrequired
object
number
string
integer
integer
CommercialEvent
commercial_eventrequired
stringrequired
stringrequired
string
string
objectrequired
objectrequired
array<object>required
object
array<object>required
array<object>required
object
array<object>required
array<object>required
CommercialEventShared
Section-filtered Commercial Event returned to an authorized recipient. Identity/version fields are always present; every other section requires an explicit grant.
commercial_eventrequired
stringrequired
stringrequired
stringrequired
objectrequired
object
array<object>
object
array<object>
array<object>
object
array<object>
array<object>
CommercialEventOperationScope
commercial_event:read | commercial_event:publish | commercial_event:append
CommercialEventSection
context | source_records | projection | evidence | relationships | conflicts | corrections | history
CommercialEventShareRequest
stringrequired
array<CommercialEventOperationScope>required
array<CommercialEventSection>required
string
CommercialEventShare
unknownrequired
stringrequired
stringrequired
stringrequired
array<CommercialEventOperationScope>required
array<CommercialEventSection>required
unknown
unknown
active | expired | revokedrequired
integerrequired
PortablePurchaseEnvelope
unknownrequired
unknownrequired
unknownrequired
PortablePurchaseRecordrequired
PortablePurchaseExtensions
PortablePurchaseRecord
stringrequired
stringrequired
pending | completed | cancelled | refunded | partially_refundedrequired
PortablePurchaseMoneyrequired
array<PortablePurchaseParticipant>required
array<PortablePurchaseSource>required
array<PortablePurchaseEvidence>
array<PortablePurchaseReference>
array<PortablePurchaseItem>
PortablePurchaseProvenancerequired
PortablePurchaseExtensions
PortablePurchaseMoney
numberrequired
stringrequired
PortablePurchaseIdentifier
stringrequired
stringrequired
PortablePurchaseDigest
stringrequired
stringrequired
PortablePurchaseParticipant
stringrequired
merchant | processor | bank | erp | enterprise | publisher | consumerrequired
string
array<PortablePurchaseIdentifier>
PortablePurchaseExtensions
PortablePurchaseReference
stringrequired
stringrequired
string
string
PortablePurchaseExtensions
PortablePurchaseSource
Must include externalId or payloadDigest. participantId must reference a record participant.
stringrequired
merchant | processor | bank | erp | enterprise | publisher | consumer | otherrequired
string
stringrequired
string
string
PortablePurchaseDigest
PortablePurchaseExtensions
PortablePurchaseEvidence
sourceId, when present, must reference a record source.
stringrequired
receipt | invoice | payment_confirmation | statement | order | delivery | otherrequired
stringrequired
string
PortablePurchaseDigest
string
PortablePurchaseExtensions
PortablePurchaseItem
string
stringrequired
number
PortablePurchaseMoney
PortablePurchaseMoney
array<PortablePurchaseReference>
PortablePurchaseExtensions
PortablePurchaseProvenance
assertedBy must reference a participant; every sourceIds entry must reference a record source.
stringrequired
stringrequired
array<string>required
string
PortablePurchaseExtensions
PortablePurchaseExtensions
Additive extension map. Every key must be vendor-namespaced, such as com.example.fulfillment.
object — Additive extension map. Every key must be vendor-namespaced, such as com.example.fulfillment.
CommercialEventContextAppend
stringrequired
stringrequired
stringrequired
stringrequired
array<object>
stringrequired
stringrequired
object
Webhooks
Register an HTTPS endpoint to receive real-time events. Viacle delivers events with a signed X-Viacle-Signature header (HMAC-SHA256 of the raw request body).
Register a webhook endpoint
{
"url": "https://your-server.com/webhooks/viacle",
"events": ["purchase.created", "purchase.updated", "purchase.gl_coded"]
}
Signature verification (Node.js)
const crypto = require("crypto");
function verifyWebhook(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const received = signatureHeader.replace("sha256=", "");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(received, "hex")
);
}
Event types
| Event | Fired when |
|---|---|
| purchase.created | A new purchase object is created and status is completed. |
| purchase.updated | Any mutable field on the purchase object is changed via PATCH. |
| purchase.gl_coded | A GL code is assigned or changed on the expense block. |
| purchase.approved | approval_status transitions to approved. |
| purchase.rejected | approval_status transitions to rejected. |
| purchase.disputed | A dispute is opened on the purchase. |
| purchase.deleted | The purchase object is soft-deleted. |
| purchase_order.match_status_changed | PO match status transitions (unmatched → two_way_matched → three_way_matched). |
| entity.created | A new entity record is created. |
| entity.updated | An entity record is updated. |
| freight.payment_risk.no_pod | EDI 210 invoice ingested but no matching POD confirmation found — payment risk flag. |
API Scopes
Every API key carries an explicit scope list. A key is only permitted to call endpoints within its granted scopes.
| Scope | Grants access to |
|---|---|
| purchases:read | GET /purchases, GET /purchases/:id, and all read paths on purchase data. |
| purchases:write | POST /purchases, PATCH /purchases/:id, DELETE /purchases/:id. |
| entities:read / :write | Entity identity endpoints — person and business profiles, spend aggregation. |
| tax:read / :write | Tax summary aggregation and 1099-ready vendor summaries. |
| expenses:read / :write | Expense management, GL coding, approval workflows. |
| webhooks:read / :write | Webhook endpoint registration and event log. |
| compliance:read / :write | Regulated spend, insurance readiness, fraud signals. |
| fdx:read / :write | FDX v6.5 transaction normalization and account linking. |
| analytics:read | Spend analytics, entity analytics, graph queries. |
| stream | Server-Sent Events real-time purchase stream. |
| policies:read / :write | Expense policy rules engine. |
| budgets:read / :write | Budget tracking and threshold alerts. |
Connectors
Viacle connects to 50+ data sources via push connectors (webhooks), pull connectors (scheduled sync), and structured format parsers. Each connector normalizes its source format into the same purchase object schema. The full interactive connector list is at viacle.io/docs.
ISO 20022 coverage
Send supported ISO 20022 messages to the parser. It preserves the payment reference, source message and type, remittance, linked authorized commercial evidence, and provenance and permissions in a Purchase Object. Authorized systems can use that object for bank reconciliation, ERP or accounting workflows, AP/AR exception review, and audit evidence.
| Coverage | Messages | Meaning |
|---|---|---|
| Accepted today | pain.001, pacs.008, camt.052, camt.053, camt.054, remt.001 | Parsed into a Purchase Object with source evidence and provenance. camt.052 and camt.053 are accepted statement evidence; remt.001 is remittance evidence. |
| Ecosystem context only | camt.035 | Proprietary Format Investigation (PrtryFrmtInvstgtn). Not supported for ingest; Viacle does not claim a camt.035 profile. |
Industry context: ISO 20022 and B2B payments reconciliation — external Finextra contributor expert opinion, not editorial endorsement.
Freight & Logistics
- EDI X12 210 (freight invoice)
- EDI X12 214 (shipment status / POD)
- FedEx (webhook)
- Flexport (pull + webhook)
- project44 (webhook)
- Loop FAP (webhook)
- Cass Transportation (pull)
E-Invoice Mandates
- PEPPOL / UBL (global)
- EDI X12 810 (US/CA)
- XRechnung (Germany)
- Factur-X / ZUGFeRD (France)
- KSeF FA_VAT v2 (Poland)
- NFe / NFCe (Brazil)
Payment Processors
- Stripe (webhook)
- Square (webhook)
- Cybersource (pull, L3)
- Checkout.com (webhook)
- Rapyd (webhook)
- WEX Fleet (pull, L3)
Document & Email
- Postmark inbound email
- Veryfi OCR (receipts + invoices)
- PDF document URL extraction
- Mobile image capture
ERP & AP Platforms
- Omie (Brazil, pull)
- Maxio / Chargify (webhook)
- EBizCharge (SOAP pull)
- Knot (webhook)
- Cybrid (stablecoin, webhook)
- MoonPay (webhook)
Banking & Open Finance
- FDX v6.5 (open banking)
- ISO 20022 (camt / pacs)
- PayPal (webhook)
- BitPay (webhook)
- Coinbase Commerce (webhook)
Idempotency
Pass an Idempotency-Key header on POST /purchases to make creation safe to retry. Duplicate requests within the deduplication window return the original response without creating a second record.
Idempotency-Key: your-unique-key-ap-2026-00831
The reference_id field provides a secondary deduplication layer: if a purchase with the same reference_id already exists under your API key, the endpoint returns 409 CONFLICT.
Security & Data Handling
| Control | Implementation |
|---|---|
| Transport | TLS 1.2+ on all endpoints. HTTP is rejected. |
| Data at rest | AES-256 encryption. |
| Card data | Full card numbers are never accepted or stored. Only last four and BIN. |
| Tenant isolation | Purchase data is scoped to your API key. No cross-account access. |
| Sandbox isolation | Sandbox keys (vi_test_sk_) cannot read or write production data. |
| Data retention | Configurable 1–3,650 days per key via PUT /api/keys/:id/retention. Auto-purged after window. |
| Audit trail | Every state change appended to an immutable event log. Query via GET /purchases/:id/events. |
| DPA | Data Processing Agreements available for enterprise customers. |
Ready to build?
Get API access, explore the interactive reference, or talk to the team.
This page is a static HTML reference — visible without JavaScript. Its endpoint inventory and schemas are generated from /openapi.json. The full interactive API reference with live examples and a sidebar navigator is at viacle.io/docs.
Generated from the current API contract. API base URL: https://api.viacle.io/api/v1.