Migrate to Unify V2
Migrating from Unify V1 is primarily an envelope change. Both contracts use the configured source mapping, so your source payload normally remains unchanged.
Recommended approach: migrate and validate in sandbox first, then move production traffic after confirming your mapped values, XML output, error handling, and bulk-processing strategy.
What changes?
| Concern | Unify V1 | Unify V2 |
|---|---|---|
| Endpoint | POST /api/v3/unify | POST /api/v3/unify |
| Selector | Omit new-api, or send false | Send new-api: true |
| Environment | env | environment |
| Purpose | Typically invoicing | mapping for the Integration Engine or invoicing for sending invoices |
| Source | { "name": "AES", "version": "1" } | "AES:1" |
| Document type | defaults.logicalDocumentType or invoice override | documentType at the root for single requests or in each invoices[] item for bulk |
| Payload | invoices[].payload | Root payload for single requests or invoices[].payload for bulk |
| Request formats | defaults and invoices envelope | Direct single document or self-contained documents in invoices |
| Validation failure | V1 result structure | HTTP 422 with source and GETS paths when available |
| Diagnostics | V1 behavior | Optional debug diagnostics |
Field mapping
For each Unify V1 invoice, make the following changes:
| Unify V1 field | Unify V2 field |
|---|---|
env | environment |
defaults.country or invoice override | country on the direct request or each bulk item |
defaults.logicalDocumentType or invoice override | documentType on the direct request or each bulk item |
defaults.source.name + defaults.source.version or invoice override | source as name:version on the direct request or each bulk item |
invoices[].payload | Root payload for a single request or the corresponding bulk item's payload |
Convert the source object to an alias string:
Unify V1: { "name": "AES", "version": "1" }
Unify V2: "AES:1"Before: Unify V1
{
"action": "submit",
"purpose": "invoicing",
"env": "sandbox",
"defaults": {
"country": "AE",
"logicalDocumentType": {
"base": "tax_invoice",
"modifiers": []
},
"source": {
"name": "AES",
"version": "1"
}
},
"invoices": [
{
"externalId": "INV-1001",
"payload": {
"invoice_data": {
"document_number": "INV-1001"
}
}
}
],
"options": {
"continueOnError": true
}
}Unify V1 requests omit the new-api header or send new-api: false.
After: Unify V2 single request
{
"country": "AE",
"environment": "sandbox",
"purpose": "mapping",
"source": "AES:1",
"documentType": {
"base": "tax_invoice",
"modifiers": []
},
"payload": {
"invoice_data": {
"document_number": "INV-1001"
}
}
}Send the new request with:
new-api: trueThis example uses mapping to process the document through the Integration Engine. Set purpose to invoicing when sending the document through the invoicing workflow.
After: Unify V2 bulk request
To preserve bulk submission, place the converted, self-contained requests in an invoices array:
{
"invoices": [
{
"country": "AE",
"environment": "sandbox",
"purpose": "mapping",
"source": "AES:1",
"documentType": {
"base": "tax_invoice",
"modifiers": []
},
"payload": {
"invoice_data": {
"document_number": "INV-1001"
}
}
},
{
"country": "AE",
"environment": "sandbox",
"purpose": "mapping",
"source": "AES:1",
"documentType": {
"base": "tax_invoice",
"modifiers": []
},
"payload": {
"invoice_data": {
"document_number": "INV-1002"
}
}
}
]
}Do not move Unify V1 wrapper fields such as action, defaults, or options into either V2 format. The invoices field is supported by the Unify V2 bulk format, but every item must contain its complete V2 controls rather than inheriting shared defaults. If your mapping expects an external identifier, keep it at its mapped location inside payload; externalId is not a document-level field in the new request.
Per-invoice overrides
A Unify V1 invoice can override shared country, source, and document-type defaults. Unify V2 has no shared defaults, so every document carries its effective controls.
When converting a Unify V1 batch, resolve each invoice's effective values before building the direct request or bulk item:
- Start with the Unify V1
defaults. - Apply any values overridden by that invoice.
- Place the resulting country, environment, purpose, source, and document type on the direct request or corresponding
invoices[]item. - Copy that invoice's
payloadto the same document object unchanged.
Bulk requests
Unify V2 supports one or more documents in an invoices array. Its bulk envelope differs from Unify V1:
- there is no shared
defaultsobject; - every
invoices[]item containscountry,environment,purpose,source,documentType, andpayload; and - the request still sends
new-api: trueas an HTTP header.
Do not reuse the full Unify V1 envelope unchanged. Convert every invoice into a self-contained Unify V2 document item.
Response handling changes
Update your client to use the HTTP status before reading the body:
| Status | Meaning |
|---|---|
200 | The document was converted and validated. |
422 | Mapping completed, but GETS or XML validation failed. Read errors. |
400, 401, 403, 404, 409, 429, 500 | Request, authentication, configuration, rate-limit, or processing failure. Read error or message. |
On success, store documentId. On 422, start with errors[].payloadPath to locate the source value and use errors[].getsPath to understand the mapped canonical field.
See Responses and Errors for the complete response reference.
Recommended rollout plan
- Inventory Unify V1 behavior. Identify bulk requests, per-invoice overrides, wrapper-level metadata, and dependencies on the V1 response shape.
- Choose a request format. Build either a direct single-document request or a bulk
invoicesarray of self-contained document requests. - Keep the source payload unchanged. Modify it only if sandbox validation identifies a source-data or mapping issue.
- Choose the purpose. Use
mappingfor the Integration Engine orinvoicingfor sending invoices. - Add
new-api: true. Send it as an HTTP header, not a body field. - Update response parsing. Handle direct
200results, structured422findings, and smaller request-error bodies. - Test representative documents. Include successful documents, invalid source data, credit notes, an unknown source, and an environment-key mismatch.
- Verify business outputs. Compare important mapped values and decode the generated XML where your workflow uses it.
- Test bulk behavior. If you use bulk requests, verify mixed success and failure handling with representative batches.
- Switch production deliberately. Use a production key, set
environmenttoproduction, and keepnew-api: trueenabled. - Monitor the rollout. Track HTTP statuses, document IDs, validation codes, and debug request IDs during the transition.
Migration checklist
- Every new request sends
new-api: trueas an HTTP header. -
envhas been renamed toenvironment. - Each document uses
mappingfor the Integration Engine orinvoicingfor sending invoices. - For single requests, document controls and one source
payloadare at the request root. - For bulk requests, every
invoices[]item contains its complete document controls andpayload. - Source name and version are combined as
name:versionfor every document. - Unify V1
defaults,action, andoptionsfields are not sent to Unify V2. - API keys match the requested environment.
- The client handles HTTP
422as a validation outcome. -
documentIdis stored on successful processing. - Bulk requests have been tested with representative documents and failure cases.
- Sandbox outputs have been verified before production rollout.
Need to remain on Unify V1 temporarily?
Unify V1 remains documented for compatibility. Continue using it by omitting new-api or sending new-api: false:
- Unify V1 Integration Guide
- Unify V1 Examples
- Unify V1 Error Codes
- Unify V1 Submission and Retrieval Flow
Avoid adding new dependencies on the Unify V1 envelope. Use Unify V2 for new development while you complete the migration.