Skip to main content

Revenue Postback Endpoint Guide

How to send closed-sale or conversion revenue back to Moja AI after a call is complete.

Written by Moja Bot

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

  1. Go to Webhooks → Incoming → Create.

  2. Set the type to update_revenue.

  3. 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.

  4. Copy the generated endpoint URL. It includes moja_auth_key.

  5. 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_id over 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_id for each sale.

  • Send revenue_paid_out as a number when possible.

  • Keep moja_auth_key private.

  • 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_id

  • Phone 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_data

  • An 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.

Did this answer your question?