Revenue Postback Endpoint Guide
Audience: Moja AI customers and technical implementers
Goal: Send closed-sale or conversion revenue back to Moja AI after a call is complete.
Overview
Moja AI’s Revenue Postback endpoint lets you update buyer/call revenue on an existing call record after the call has already happened.
Use this when the final sale, conversion, or billable event is confirmed outside Moja AI, such as in a CRM, buyer platform, order system, or internal billing workflow.
What this updates
This endpoint updates revenue_paid_out.
revenue_paid_out represents buyer/call revenue on the call record.
What this does not update
This endpoint does not set publisher payout.
It also does not reliably recalculate percentage-based publisher payout or publisher margin. Publisher economics remain controlled by campaign, publisher, and internal adjustment configuration.
Buyers should only send buyer-side revenue. They should not be asked to send publisher payout or margin.
To change publisher payout or make broader multi-field patches, use reporting tools or the appropriate field-update workflow — not this endpoint.
Setup
Go to Webhooks → Incoming → Create.
Set the type to
update_revenue.Set Caller ID Match Days from 1–7 days if you will ever match calls by phone number. The default in the UI is 7 days.
Copy the generated endpoint URL. It includes
moja_auth_key.Optional: link the webhook on a campaign under Incoming Webhooks.
Linking is optional for update_revenue. Revenue updates are scoped by the organization auth key; campaign attachment does not restrict which calls can be updated.
Prefer copying the exact URL from Webhooks → Incoming after creation. The copied URL is the source of truth if configuration changes.
Endpoint
POST or GET https://webhooks.moja.cloud/update-revenue?moja_auth_key=YOUR_AUTH_KEY
Required header for POST
Content-Type: application/json
Authentication
Authenticate with moja_auth_key as a query parameter on the URL.
Header-based authentication is not supported for this endpoint.
Keep the key private. Query strings can appear in server logs, analytics logs, proxies, or debugging tools. Only share it with trusted systems.
Missing or invalid authentication returns 401 Unauthorized. Rate-limited requests may return 429 Too Many Requests.
Matching calls
Preferred: match by Call Log ID
Use call_log_id whenever possible. This is the most reliable way to update the correct call.
{ "call_log_id": "abc123-def456-ghi789", "revenue_paid_out": 150.00, "transaction_id": "order-10001"}
Advanced: update multiple Call Log IDs
You may send an array of up to 50 call_log_id values when the same revenue amount should be applied to multiple known call logs.
{ "call_log_id": [ "abc123-def456-ghi789", "def456-ghi789-jkl012" ], "revenue_paid_out": 150.00, "transaction_id": "order-10001"}
Do not combine a call_log_id array with phone-number matching.
Secondary: match by phone number
If call_log_id is not available, you may match by phone number.
{ "phone_number": "+13105559876", "revenue_paid_out": 150.00, "transaction_id": "order-10001"}
phone_number matches the caller ANI, also called inbound caller ID. It does not match the dialed campaign number.
Use E.164 format when possible, such as +13105559876. Digits-only formatting may work depending on the matcher, but E.164 is preferred.
Phone matching uses the webhook’s Caller ID Match Days setting, from 1–7 days.
If multiple calls match that caller ID in the configured window, all matching call logs are updated.
Do not use phone matching when a single sale must update exactly one call. Use call_log_id instead.
Revenue format
Send revenue_paid_out as a JSON number.
Correct:
"revenue_paid_out": 150.00
Also accepted:
"revenue_paid_out": "150.00"
Do not send a currency-formatted string:
"revenue_paid_out": "$150.00"
The canonical public field name is revenue_paid_out.
Timing
Send the revenue postback after the call is complete and the final sale or conversion amount is known.
If the postback is sent too early, before connected duration is finalized, Moja may reject the update.
Example error:
Cannot update revenue on a call with no connected duration.
If this happens, replay the postback once the call is completed and connected duration exists.
Do not assume Moja will silently retry early postbacks automatically.
Idempotency
Include a stable transaction_id for each external sale, order, or conversion.
"transaction_id": "order-10001"
When the same organization and transaction_id are sent again after a completed attempt, Moja returns the original stored response instead of applying the request as a new event.
If a request with that transaction_id is still in flight, Moja may return 409 Conflict.
Server-side idempotency is best effort. On rare infrastructure errors, idempotency checks may fail open. Make the sending system safe: use one stable transaction_id per sale and never retry the same sale under a new transaction_id.
Success response
A successful response confirms that Moja accepted the revenue update for the matched call log IDs.
{ "success": true, "call_log_ids": ["abc123-def456-ghi789"], "revenue_paid_out": 150}
Trust the response body. Incoming request history may show a blank call_log_id even when call_log_ids, or failed_call_log_ids on errors, appear in the response.
transaction_id is used for idempotency and logging, but may not be echoed in the success response.
Partial success
When updating multiple call logs, some records may update while others fail.
A partial response may include fields such as partial_success, failed_call_logs, or failures. Review the response body before marking the external sale as fully synced.
Best practices
Prefer
call_log_idover phone matching.Use phone matching only when updating every matching call in the configured caller-ID window is acceptable.
Send the postback after the call is complete and connected duration exists.
Include a stable, unique
transaction_idfor each sale.Send
revenue_paid_outas a number when possible.Keep
moja_auth_keyprivate.Log request and response details in the external system.
Test with a known completed call before going live.
Troubleshooting
401 Unauthorized
Check that moja_auth_key is included in the URL and valid.
429 Too Many Requests
The endpoint is rate limited. Slow down requests and retry later.
409 Conflict
A request with the same transaction_id may already be in flight. Wait, then retry using the same transaction_id.
422: No connected duration
The postback may have arrived before the call completed or before connected duration was finalized.
Replay the postback after the call is complete.
Call Log Not Found
Check:
call_log_idPhone number formatting
Whether the phone number is E.164
Whether phone matching is using the caller ANI, not the dialed campaign number
Whether the call is inside the webhook’s Caller ID Match Days window
Whether the auth key belongs to the correct organization
Revenue did not update
Confirm the payload uses:
"revenue_paid_out": 150.00
Do not send:
"revenue_paid_out": "$150.00"
Multiple calls updated from one phone number
If multiple calls match the caller ID within the configured Caller ID Match Days window, all matching call logs are updated.
Use call_log_id when the sale should update exactly one call.
Duplicate revenue updates
Include a stable transaction_id for each conversion or order.
Do not retry the same sale with a new transaction_id.
What this endpoint is not
This endpoint is not:
Pre-call
call_dataAn outgoing webhook
An RTB bid endpoint
A bulk reporting adjustment API
A publisher payout or margin update endpoint
Related
For sending conversion events out of Moja AI, see outgoing conversion webhooks.
