Polling (legacy)
Periodically check MAPI for pending inbound messages and the status of outbound messages. Supported for existing integrations; new integrations should use webhooks.
Legacy pattern. Polling remains supported, but new integrations should use webhooks, which deliver notifications in near real-time without repeated API calls.
With polling, your back-end calls MAPI on a schedule to check whether new inbound messages are waiting to be imported, and what has happened to the messages it sent.
sequenceDiagram
participant E as Your back-end (ERP)
participant U as Unimaze
loop Every 10–30 minutes
E->>U: GET /messages?status=pendingdelivery&transfer=inbound
U-->>E: List of pending messages
E->>U: GET /transactions/submit-invoice?messageId=:mid
U-->>E: Document data (JSON)
E->>U: POST /messages/:mid/mark-as-delivered
end
How it works
Inbound messages
- Call
GET /messages?status=pendingdelivery&transfer=inboundto list pending inbound messages. Page through the results withoffsetandlimit(default50). - For each message, fetch the document data based on its
action. - Import the document into your back-end.
- Call
POST /messages/:mid/mark-as-deliveredorPOST /messages/:mid/mark-as-failedso the message no longer appears in the pending list.
The full steps are described in Receiving inbound messages.
Outbound messages
For each message you have sent that has not reached a final state yet, call GET /messages/:mid/status and update the document in your back-end. Stop checking a message when it reaches a final state: delivered or failed (or parked, if handled manually in MUI). pendingfailure is not final: in rare cases manual handling delays the final state, and the message then becomes failed or delivered.
Recommendations
- Poll every 10–30 minutes. More frequent polling adds load without much benefit. If you need faster reactions, use webhooks.
- Always mark messages as delivered or failed. Otherwise they are returned by every poll.
- Show pending counts to users. Use
GET /parties/{isoIdentifier}/pending-summariesto show a badge or alert in your application. It returns the number of documents in each pending status, with a localized subject and a link to those documents in Unimaze.transfergives the direction of each status:incomingfor received documents waiting for your system,outgoingfor documents you sent that wait for review or booking. To show, for example, only billing documents waiting for your system, filter by action with theactionsquery parameter and use the statuses wheretransferisincoming:GET /parties/{isoIdentifier}/pending-summaries?actions=SubmitInvoice,CorrectWithCredit,SubmitBillingResponse.
Moving from polling to webhooks
Webhooks trigger the same logic you already have, so the move is small. Move both directions, so you stop polling for inbound messages and for outbound status:
- Expose an HTTPS endpoint, add it as a webhook endpoint and route both Inbound messages and Outbound messages to it (see Setting up webhooks). The first endpoint you add receives all categories automatically.
- Inbound: when a
deliveryNotifiedevent arrives, verify the signature and run your existing fetch-import-mark steps for that one message, usingmessageIdfrom the body. - Outbound: when a
messageStatusChangedevent arrives, update the document in your back-end fromnewValue(for exampledeliveredorfailed) instead of callingGET /messages/:mid/status. Tax reporting and lifecycle changes arrive the same way (taxReportingStatusChanged,lifecycleStatusChanged). - If you use pending import messages (
GET /messages/pending-import), handleimportNotifiedthe same way as inbound messages and acknowledge withmark-as-imported(see Pending import messages). - Keep a polling job, but reduce it to a low frequency (for example daily) as a safety net: pending inbound messages that were notified but never acknowledged (see Unacknowledged messages), and outbound messages still without a final status.
Updated about 1 hour ago
