中文
Documentation menu

Developer Hub/Partner Event API

Partner API v1 · Event catalog v5

Partner Event API

Send one destination business event to MeetROAS. Every request is signed with account credentials and carries the Click ID value in the fixed mr_click_id field. The destination URL query key defaults to mr_clickid and is customer-configurable.

1. Receive the complete handoff package

The destination engineer does not need dashboard access. Ask the customer account Admin for one account-level complete handoff package and verify every item below:

  • Key ID + Secret
  • Production, validation, catalog, OpenAPI, Developer Hub, and Playground URLs
  • Actual App / Campaign name, host, traffic source, and destination URL query key
  • Fixed system test App + mrt_ + expiry
  • Signing, body-size, rate-limit, retry, and error contracts

Account testing never selects a customer App / Campaign and does not include a production query key. The buyer supplies the real Campaign query key and mrc_ path in the separate launch workflow.

Validate in the self-service playground

2. Capture and return the Click ID

MeetROAS appends the Click ID to the destination URL. The query key is configured per customer App and defaults to mr_clickid. Read and persist its value, then send that same value in the fixed mr_click_id Partner Event JSON field.

Destination URL
https://casino.example/register?mr_clickid=mrc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Do not parse, modify, or mint this value.
  • Do not use the Key ID or Secret as mr_click_id.
  • Do not assume every customer uses mr_clickid as the URL key; use the actual campaign URL supplied by that customer.
  • Production mrc_ IDs remain valid for 30 days; unknown, expired, or account-mismatched IDs return 404.

End-to-end testing without ad spend

The complete handoff provides an mrt_ for the fixed system test App. Persist it, send it as mr_click_id, and set test: true. MeetROAS validates attribution, schema, and idempotency in Test Runs without source planning, postbacks, or production-performance impact.

Test destination URL
https://casino.example/register?mr_clickid=mrt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

test: true must use mrt_. Production requests omit test and use an mrc_ created by real traffic. After testing, remove test; never rewrite mrt_ into mrc_.

3. Build headers and the HMAC signature

HeaderValueProduced by
Content-Typeapplication/jsonFixed by the destination
X-MeetROAS-Keymrk_…Created by the MeetROAS account Admin
X-MeetROAS-TimestampCurrent 10-digit Unix secondsGenerated for every request
X-MeetROAS-Signaturev1=<64 lowercase hex>Computed with the Secret; it is not a separate credential
  1. Serialize the final JSON raw body first.
  2. Set timestamp = floor(current_time_ms / 1000).
  3. The signing input is timestamp + '.' + raw_body.
  4. Compute HMAC-SHA256 with the Secret, encode lowercase hex, then prefix v1=.
Signing input (no added spaces or newline)
1786344000.{"event_id":"payment-123",...}

Send the exact body that was signed. Re-indenting, reordering fields, or adding a newline invalidates the signature. Server time must be within five minutes of UTC.

4. Validate the integration

POST https://api.meetroas.com/v1/events/validate

The validation endpoint applies the same credentials, headers, signature, and schema as production without creating a production event or triggering a traffic-platform conversion.

Choose your server language

Each example serializes the body once, signs those exact bytes, and sends them to the validation endpoint without creating a production event.

Node.js 20+
import { createHmac, randomUUID } from "node:crypto";

const keyId = process.env.MEETROAS_KEY_ID;
const secret = process.env.MEETROAS_SECRET;
if (!keyId || !secret) throw new Error("Missing MeetROAS credentials");

const body = JSON.stringify({
  event_id: `test-${randomUUID()}`,
  mr_click_id: "mrt_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  event: "deposit",
  occurred_at: new Date().toISOString(),
  value: 49.95,
  currency: "USD",
  test: true,
});
const timestamp = String(Math.floor(Date.now() / 1000));
const digest = createHmac("sha256", secret)
  .update(`${timestamp}.${body}`, "utf8")
  .digest("hex");

const response = await fetch("https://api.meetroas.com/v1/events/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-MeetROAS-Key": keyId,
    "X-MeetROAS-Timestamp": timestamp,
    "X-MeetROAS-Signature": `v1=${digest}`,
  },
  body,
});
console.log(response.status, await response.text());
Successful response
{
  "valid": true,
  "authentication": "valid",
  "schema": "valid",
  "event": "deposit",
  "catalog_version": 2,
  "test": true
}

The response catalog_version is the normalized identity version for that event. Existing event shapes retain their original v1/v2 identity so retries of an existing event_id remain stable; read the machine event catalog for the current accepted-catalog version.

The destination engineer can enter the Key ID and Secret in the playground to run the same signing, schema, and rejection checks. The Secret remains only in that browser tab's memory.

5. Send test events, then switch to production

POST https://api.meetroas.com/v1/events

application/json
{
  "event_id": "test-93951c0c-446a-4dfb-861e-a9083d453cf4",
  "mr_click_id": "mrt_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "event": "deposit",
  "occurred_at": "2026-09-24T21:12:53.916Z",
  "value": 49.95,
  "price": 0.01,
  "currency": "USD",
  "user_data": {
    "email_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "phone_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "external_id_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
  },
  "client": {
    "ip": "192.0.2.10",
    "user_agent": "Mozilla/5.0 (Example Browser)",
    "page_url": "https://destination.example/complete",
    "referrer_url": "https://destination.example/checkout",
    "meta_fbp": "fb.1.1788480000000.1234567890",
    "tiktok_ttp": "synthetic-test-ttp"
  },
  "test": true
}
FieldJSON typeRequiredFormat and semantics
event_idstringYesDestination-generated idempotency key, 1–128 characters, no personal data; preserve it for retries of the same business fact.
mr_click_idstringYesFixed API field whose value comes from the customer-configured destination Click ID query key (default mr_clickid).
eventstringYesMust be present in the accepted event catalog below.
occurred_atstringYesISO-8601 UTC; within 31 days generally, and within seven days with no more than five minutes of future skew for Meta/TikTok.
valuenumberOptional for monetary eventsDestination-reported conversion value or revenue. From 0 to 1,000,000,000 with up to six decimals; not minor units and never converted by MeetROAS.
pricenumberOptional for monetary eventsDestination-reported conversion cost. It is independent from value and may be sent alone or together with value.
currencystringOptionalUppercase ISO 4217 code; requires value or price. MeetROAS never guesses a currency.
user_dataobjectOptionalLowercase SHA-256 values lawfully collected with consent for ad measurement: email_sha256, phone_sha256, and external_id_sha256. Never send raw personal data.
clientobjectOptionalEvent-time browser ip, user_agent, HTTPS page_url/referrer_url without query or fragment, plus meta_fbp/tiktok_ttp; never send destination-server context. TikTok recommends supplying ip and user_agent together.
testbooleanTest onlySet true with mrt_ for tests. Remove the field and use mrc_ for production.

user_data / client fields

Both objects and all their fields are optional. Omit unavailable values; do not send null, arrays or unknown fields. Amounts are JSON numbers (49.95, not "49.95"); test is a boolean. The example hashes, IP and cookies are synthetic format examples, not real visitor data to submit. Use actual browser context with the lawful basis and consent for ad measurement.

FieldJSON typeRequiredFormat and constraints
user_data.email_sha256stringOptionalLowercase hexadecimal SHA-256, exactly 64 characters
user_data.phone_sha256stringOptionalLowercase hexadecimal SHA-256, exactly 64 characters
user_data.external_id_sha256stringOptionalLowercase hexadecimal SHA-256, exactly 64 characters
client.ipstringOptionalEvent-time visitor IP string; 2–45 characters using only 0–9, A–F, a–f, colon and dot
client.user_agentstringOptionalEvent-time browser User-Agent; 1–1024 characters, no control characters
client.page_urlstringOptionalHTTPS URL, at most 2048 characters; no credentials, query or fragment
client.referrer_urlstringOptionalHTTPS URL, at most 2048 characters; no credentials, query or fragment
client.meta_fbpstringOptionalActual Meta _fbp cookie; 1–256 alphanumeric, dot, underscore or hyphen characters
client.tiktok_ttpstringOptionalActual TikTok _ttp cookie; 1–256 alphanumeric, dot, underscore or hyphen characters

MeetROAS stores value and price separately and projects them only to semantically matching fields supported by the source. TrafficStars can receive value (revenue) and price (CPA cost); PropellerAds payout, ExoClick value, MGID r, and BidVertiser revenue receive value only; HilltopAds price and Adsterra atpay receive price only; RichAds receives no monetary field. Optional match data is encrypted only in the pending delivery payload and cleared after seven days. Changing money, event semantics, or match data under the same event_id returns 409. Meta/TikTok events must arrive within seven days.

6. Accepted events

The event field must use one of these keys. Use the machine-readable catalog as the authoritative source for automated validation.

A casino or destination sends only the events it actually supports and has enabled; it does not have to implement or send the full catalog. The destination is the producer of each business fact. In particular, the casino determines first_day_deposit, and MeetROAS does not derive or calculate the first day.

Event keyWhen to sendRepeatabilityevent_id policyMoney
account_registration
Account registration
The user completed the destination platform's account registration flow; a page view or incomplete form does not qualify.once_per_clickUse one stable ID for the registration and preserve it across retries.Forbidden
first_deposit
First deposit
The account's first verified deposit became effective; pending or failed transactions do not qualify.once_per_clickSend once per account and preserve the same ID across retries.Optional
first_day_deposit
First-day first deposit
The destination sends this after the casino determines that the player's first effective deposit, top-up, or purchase on the first day has completed. MeetROAS validates, stores, and routes the fact; it does not derive the first day from registration dates, time zones, or transaction history.once_per_accountSend once per player or account. Use one stable ID for the same first-day first-deposit fact and all of its retries.Optional
deposit
Deposit
A verified deposit became effective; this event is repeatable.repeatableUse a distinct ID per transaction and preserve it when retrying that transaction.Optional
login
Login
The destination verified the credentials and created a new authenticated login session; failed attempts, refreshes of an existing session, and login-page views do not qualify.repeatableUse a distinct ID for each successful login session and preserve it when retrying that login.Forbidden

GET https://api.meetroas.com/v1/events/catalog

7. Supported traffic platforms

The destination implements the Partner Event API once; MeetROAS connects it to the traffic platform configured by the customer.

StatusTraffic platforms
SupportedMeta (Facebook CAPI) · TikTok Events API · TrafficStars · PropellerAds · RichAds · ExoClick · HilltopAds · EvaDav · BidVertiser · AdMaven · AdsGram · Kadam · Adsterra · GeeMee · MGSkyAds
Coming soonMGID

8. Responses, retries, and go-live

The limit is 300 requests per 60 seconds for each Key ID and endpoint scope. The raw-body limit is 16384 bytes, timestamp tolerance is 300 seconds, and the recommended client timeout is 10 seconds. A 429 includes Retry-After: 60. Use 2, 4, 8, 16, and 32 second exponential backoff with jitter, for at most five retries; then require investigation without changing event_id or rebuilding the body.

HTTPMeaningAction
200Validation passed, or a test/production event is an already processed duplicateSuccess; do not mint a new event_id for the retry
202Test/production event accepted for the first timeSuccess; do not retry
400/415Invalid JSON, field, or Content-TypeFix before retrying
401Invalid Key, timestamp, or signatureCheck credentials, server time, and the exact raw body
404The endpoint cannot resolve the test/production mr_click_idConfirm the matching redirect parameter was persisted and has not expired
409event_id already identifies different business factsStop automatic retries and investigate idempotency
429/5xxTemporary limit or service errorExponential backoff with jitter; preserve event_id and body

A fixed account test must return integration_status=passed and delivery_readiness=not_applicable. This proves the destination integration without depending on a buyer, Goal Binding, or connector.

  1. Obtain credentials and pass the validation endpoint.
  2. Use the fixed test mrt_ from the complete package and send the supported event sequence to the production endpoint with test: true.
  3. Confirm attribution, schema, duplicate, and conflict semantics in Test Runs; no postback is planned or sent.
  4. After real traffic begins, persist the real mrc_, remove the test field, and only then send production business events.

9. Engineering go-live check

This checklist confirms that your backend integration is ready. Once complete, engineers do not change code for each Campaign; the buyer supplies the actual query key and configures Campaigns and conversion events during launch.

My backend handoff checklist
0 / 7Confirm that your backend meets every production requirement.

10. Security requirements

  • Store the Secret only in a server-side secrets manager.
  • Never put the Secret in a URL, browser code, support ticket, or application log.
  • Use a fresh timestamp for every request and sign the exact raw body that will be sent.
  • If a credential is lost or exposed, replace only that destination's Key. Revoke its old Key after the new package is saved; other destinations remain active.