Skip to content
Draft — not yet reviewedThis article is a starter draft. The steps may not match the product exactly yet.

Send revenue postbacks

Who this is for: Engineers connecting a CRM, order system, buyer platform, or billing workflow to Moja. What you’ll need: An incoming webhook of type update_revenue, its auth key, and a completed test call. Time required: About 20 minutes.

The revenue postback endpoint updates buyer revenue on a call record that already exists. Use it when the final sale, conversion, or billable amount is confirmed somewhere outside Moja and needs to be written back against the call that produced it.

It updates one field: revenue_paid_out, which represents buyer or call revenue on the call record. revenue_paid_out is the canonical public field name.

It is also not a pre-call call_data webhook, an outgoing webhook, an RTB bid endpoint, or a bulk reporting adjustment API. See Webhooks for those.

  • Confirm you have access to Webhooks → Incoming in the Moja portal.
  • Know which identifier your external system can supply for a call. call_log_id is strongly preferred over phone number.
  • Have one completed test call available with a real connected duration.
  1. Create the incoming webhook.

    Go to Webhooks → Incoming → Create and set the type to update_revenue.

  2. Set the caller ID match window.

    Set Caller ID Match Days between 1 and 7 days if you will ever match calls by phone number. The UI default is 7 days. If you will only ever match by call_log_id, this setting does not apply.

  3. Copy the generated endpoint URL.

    The URL includes your moja_auth_key. Copy it from the portal after creation rather than assembling it by hand — the copied URL is the source of truth if configuration changes.

    Expected result: you hold a URL of the form https://webhooks.moja.cloud/update-revenue?moja_auth_key=YOUR_AUTH_KEY.

  4. Optionally link the webhook to a campaign.

    Under the campaign’s Incoming Webhooks section. Linking is optional for update_revenue: revenue updates are scoped by the organization auth key, and campaign attachment does not restrict which calls can be updated.

POST or GET https://webhooks.moja.cloud/update-revenue?moja_auth_key=YOUR_AUTH_KEY

POST requests require Content-Type: application/json.

Authentication is moja_auth_key as a query parameter. Header-based authentication is not supported for this endpoint. Missing or invalid authentication returns 401 Unauthorized; rate-limited requests may return 429 Too Many Requests.

Terminal window
curl -X POST 'https://webhooks.moja.cloud/update-revenue?moja_auth_key=YOUR_AUTH_KEY' \
-H 'Content-Type: application/json' \
-d '{
"call_log_id": "abc123-def456-ghi789",
"revenue_paid_out": 150.00,
"transaction_id": "order-10001"
}'

Response:

{
"success": true,
"call_log_ids": ["abc123-def456-ghi789"],
"revenue_paid_out": 150
}
Parameter Tier Type Notes
moja_auth_key Required query string On the URL. Header auth is not supported
revenue_paid_out Required number JSON number such as 150.00. A numeric string is accepted; a currency string such as "$150.00" is not
call_log_id Required unless matching by phone string or array The preferred matcher. Also accepts callLogId, call_sid, callSid. Up to 50 values in an array
phone_number Required if no call_log_id string Also accepts phoneNumber. Matched against the caller ANI, not the dialed campaign number. E.164 preferred
transaction_id Recommended string Idempotency key. One stable value per external sale, order, or conversion

If both call_log_id and phone_number are supplied, call_log_id takes priority.

Prefer call_log_id whenever your system can carry it. It updates exactly the call you mean.

Phone matching is the fallback. It uses the webhook’s Caller ID Match Days window (1–7 days), and if several calls match that caller ID inside the window, all of them are updated. Never use phone matching when a single sale must update exactly one call.

Send the postback after the call is complete and the final amount is known. If it arrives before connected duration is finalized, Moja may reject it:

Cannot update revenue on a call with no connected duration.

Replay the postback once the call has completed and connected duration exists. Do not assume Moja will silently retry an early postback on your behalf.

If the call’s converted_at timestamp is not already set, updating revenue sets it to the current time.

Include a stable transaction_id per external sale. 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 ID is still in flight, you may get 409 Conflict — wait, then retry with the same ID.

Server-side idempotency is best effort and can fail open on rare infrastructure errors, so make the sending system safe: one stable ID per sale, and never retry the same sale under a new ID.

Code Meaning What to do
200 Accepted. Body lists the updated call_log_ids Mark the sale synced after checking the body, not just the status code
401 Missing or invalid moja_auth_key Recopy the URL from Webhooks → Incoming
409 A request with the same transaction_id is in flight Wait, then retry with the same transaction_id
422 No connected duration on the call Replay after the call completes
429 Rate limited Slow down and retry later

When updating several call logs, some can succeed while others fail. A partial response may include fields such as partial_success, failed_call_logs, or failures. Read the body before marking the external sale fully synced.

  1. Pick one completed call with a known call_log_id and a real connected duration.

  2. Post a small distinctive amount against it, with a transaction_id you can recognise later.

  3. Confirm the response is 200 and that call_log_ids contains the ID you sent.

  4. Open that call in reporting and confirm the revenue value changed.

  5. Send the exact same request again. Confirm you get the stored original response back rather than a second update, which proves your idempotency key is working.

  6. Send once with a deliberately wrong auth key and confirm 401.

Symptom Likely cause Fix
401 Unauthorized moja_auth_key missing from the URL or invalid Copy the exact URL from Webhooks → Incoming; do not send the key as a header
429 Too Many Requests Rate limited Slow the send rate and retry
409 Conflict Same transaction_id still in flight Wait, then retry with the same ID
422, no connected duration Postback sent before the call finished Replay after completion
Call log not found Wrong call_log_id, wrong phone format, matching against the dialed number instead of the ANI, outside the match window, or the key belongs to another organization Work down that list in order
Revenue did not change Currency-formatted amount such as "$150.00" Send 150.00 as a number
Several calls updated from one postback Phone matching hit multiple calls in the Caller ID Match Days window Use call_log_id when the sale should update exactly one call
Duplicate revenue recorded The same sale was retried under a new transaction_id Use one stable ID per sale and reuse it on every retry
  • Prefer call_log_id over phone matching.
  • Use phone matching only when updating every matching call in the window is acceptable.
  • Send after the call is complete and connected duration exists.
  • Send revenue_paid_out as a number.
  • Include a stable, unique transaction_id per sale.
  • Log both request and response in the external system.
  • Test against a known completed call before going live.