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

How Moja exchanges data with systems outside it: the endpoints you call, the requests we send you, and the fields on both sides.

Developers

This section documents how Moja exchanges data with systems outside it: the endpoints you call, the requests we send you, and the fields on both sides.

It is written for engineers and technical implementers. If you are setting up a campaign in the portal for the first time, start with Get started as a buyer or network or Get started as a publisher instead.

The v1 REST API manages the records you otherwise configure in the portal — campaigns, targets, buyers, publishers, routing plans, RTB formulas, numbers and pools, webhooks, custom tags, audit logs, and reporting. 90 operations across 18 resource groups.

Start here

It is a separate surface from the four below, on its own host (external-api.moja-ai.com) with its own authentication (X-API-Key or a bearer token). The four integration surfaces move call traffic and call data; the REST API manages configuration and reporting.

The four integration surfaces

You want to Use
Create or update campaigns, targets, buyers, or publishers from your own system REST API
Pull call logs or reporting into a warehouse or BI tool REST API — Reporting
Provision phone numbers or number pools programmatically REST API — Numbers, Number pools
Send call opportunities to a buyer running Moja RTB — publisher direction
Auction your calls to multiple external buyers RTB — outbound direction
Get a notification in your system when a call happens Outbound webhooks
Push caller metadata into Moja before routing Inbound webhooks — call_data
Report a closed sale back against a call Revenue postbacks
Attribute website calls to campaigns and ad clicks DNI

These hold across the whole section unless a page says otherwise.

Surface Base URL
REST API https://external-api.moja-ai.com (paths under /api/v1)
Inbound webhooks and postbacks https://webhooks.moja.cloud
Inbound RTB https://rtb.moja.cloud

Outbound webhooks and outbound RTB requests go to your endpoint or your buyer’s, not to a Moja base URL. You supply that URL when you configure the target.

Authentication differs by surface, so check the page you are working from:

  • The REST API authenticates with an organization API key, sent as an X-API-Key header or as Authorization: Bearer <api_key>. It does not use moja_auth_key, and the key never goes in the query string. See REST API authentication.
  • Inbound webhooks and revenue postbacks authenticate with moja_auth_key as a query parameter on the URL. Header-based authentication is not supported. A missing or invalid key returns 401 Unauthorized.
  • Inbound RTB endpoints are scoped by the identifier in the URL your buyer supplies.
  • Outbound webhooks authenticate however your receiving endpoint requires — you define the headers, including any Authorization header, in the webhook template.

Treat moja_auth_key as a secret. Query strings can be captured in server logs, proxies, analytics, and debugging tools, so share the URL only with systems you trust.

Send phone numbers in E.164 format — a leading +, country code, then the national number, with no spaces or punctuation. For example: +13105559876.

Digits-only formats are tolerated in some matchers, but E.164 is the format to build against. When matching a call by phone number, note that the value is matched against the caller’s ANI (inbound caller ID), not the number they dialed.

REST API responses. Record timestamps on the v1 REST API — created_at, updated_at, and paused_until — are declared as OpenAPI date-time in the published specification, which is RFC 3339 (2026-08-28T14:05:00Z). Build against that for those fields.

Campaigns and targets each carry their own configured timezone, which affects schedules and caps. Reporting timestamps follow that configuration rather than your local time.

Send monetary amounts as JSON numbers, for example 150.00. A numeric string such as "150.00" is also accepted. Currency-formatted strings such as "$150.00" are not.

Where an endpoint supports it, send a stable transaction_id per external event — one ID per sale, order, or conversion, reused on every retry of that same event. Never retry the same event under a new ID.

Include the request timestamp, the complete request and response bodies, and the request_id or call_log_id in any support conversation. Those three things resolve most integration questions in one round trip.