meetroas中文
Documentation menu

Developer Hub/Partner Event API

Partner API v1 · Event catalog v2

Partner Event API

Send one destination business event to MeetROAS. Every request is signed with account credentials and carries the mr_click_id received when the visitor reached the destination.

1. Obtain a Key ID and Secret

  1. A MeetROAS customer account Admin signs in to app.meetroas.com.
  2. Open Conversions → Destination partner API.
  3. Select Create credential. The dashboard displays a Key ID and Secret.
  4. Store both values immediately in the destination platform's secrets manager. The Secret cannot be read again after leaving the page.

No MeetROAS support or partner contact is required. The customer account Admin creates the credential and sends it to the destination engineering team through a secure channel; rotate it from the same page if lost.

2. Receive and persist mr_click_id

MeetROAS appends mr_click_id to the destination URL. Read it on the landing request and persist it with the server-side visitor or transaction record.

Destination URL
https://casino.example/register?mr_click_id=mrc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Do not parse, modify, or mint this value.
  • Do not use the Key ID or Secret as mr_click_id.
  • mr_click_id remains valid for 30 days; unknown, expired, or account-mismatched IDs return 404.

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+
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: "mrc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  event: "purchase",
  occurred_at: new Date().toISOString(),
  value: 49.95,
  currency: "USD",
});
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());
Java 11+
Java 11+
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class MeetROASExample {
  public static void main(String[] args) throws Exception {
    String keyId = requireEnv("MEETROAS_KEY_ID");
    String secret = requireEnv("MEETROAS_SECRET");
    String body = String.format(
      "{\"event_id\":\"test-%s\",\"mr_click_id\":\"mrc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"," +
      "\"event\":\"purchase\",\"occurred_at\":\"%s\",\"value\":49.95,\"currency\":\"USD\"}",
      UUID.randomUUID(), Instant.now());
    String timestamp = Long.toString(Instant.now().getEpochSecond());
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
    byte[] digest = mac.doFinal((timestamp + "." + body).getBytes(StandardCharsets.UTF_8));
    StringBuilder hex = new StringBuilder();
    for (byte value : digest) hex.append(String.format("%02x", value & 0xff));
    HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.meetroas.com/v1/events/validate"))
      .header("Content-Type", "application/json")
      .header("X-MeetROAS-Key", keyId)
      .header("X-MeetROAS-Timestamp", timestamp)
      .header("X-MeetROAS-Signature", "v1=" + hex)
      .POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8)).build();
    HttpResponse<String> response = HttpClient.newHttpClient()
      .send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.statusCode() + " " + response.body());
  }
  private static String requireEnv(String name) {
    String value = System.getenv(name);
    if (value == null || value.isBlank()) throw new IllegalStateException("Missing " + name);
    return value;
  }
}
Go 1.22+
Go 1.22+
package main

import (
  "bytes"
  "crypto/hmac"
  "crypto/sha256"
  "encoding/hex"
  "encoding/json"
  "fmt"
  "io"
  "net/http"
  "os"
  "strconv"
  "time"
)

type event struct {
  EventID string `json:"event_id"`
  ClickID string `json:"mr_click_id"`
  Event string `json:"event"`
  OccurredAt string `json:"occurred_at"`
  Value float64 `json:"value"`
  Currency string `json:"currency"`
}

func main() {
  keyID, secret := os.Getenv("MEETROAS_KEY_ID"), os.Getenv("MEETROAS_SECRET")
  if keyID == "" || secret == "" { panic("missing MeetROAS credentials") }
  body, err := json.Marshal(event{
    "test-" + strconv.FormatInt(time.Now().UnixNano(), 10), "mrc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "purchase", time.Now().UTC().Format(time.RFC3339), 49.95, "USD",
  })
  if err != nil { panic(err) }
  timestamp := strconv.FormatInt(time.Now().Unix(), 10)
  mac := hmac.New(sha256.New, []byte(secret))
  mac.Write(append([]byte(timestamp+"."), body...))
  req, err := http.NewRequest("POST", "https://api.meetroas.com/v1/events/validate", bytes.NewReader(body))
  if err != nil { panic(err) }
  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("X-MeetROAS-Key", keyID)
  req.Header.Set("X-MeetROAS-Timestamp", timestamp)
  req.Header.Set("X-MeetROAS-Signature", "v1="+hex.EncodeToString(mac.Sum(nil)))
  response, err := http.DefaultClient.Do(req)
  if err != nil { panic(err) }
  defer response.Body.Close()
  responseBody, _ := io.ReadAll(response.Body)
  fmt.Printf("%d %s\n", response.StatusCode, responseBody)
}
C# · .NET 8+
C# · .NET 8+
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

var keyId = RequireEnv("MEETROAS_KEY_ID");
var secret = RequireEnv("MEETROAS_SECRET");
var body = JsonSerializer.Serialize(new {
  event_id = $"test-{Guid.NewGuid()}",
  mr_click_id = "mrc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  @event = "purchase",
  occurred_at = DateTimeOffset.UtcNow.ToString("O"),
  value = 49.95,
  currency = "USD",
});
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var digest = hmac.ComputeHash(Encoding.UTF8.GetBytes($"{timestamp}.{body}"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.meetroas.com/v1/events/validate");
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
request.Headers.Add("X-MeetROAS-Key", keyId);
request.Headers.Add("X-MeetROAS-Timestamp", timestamp);
request.Headers.Add("X-MeetROAS-Signature", $"v1={Convert.ToHexString(digest).ToLowerInvariant()}");
using var response = await new HttpClient().SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");

static string RequireEnv(string name) => Environment.GetEnvironmentVariable(name)
  ?? throw new InvalidOperationException($"Missing {name}");
Successful response
{
  "valid": true,
  "authentication": "valid",
  "schema": "valid",
  "event": "purchase",
  "catalog_version": 2
}

The customer account Admin can also select Validate signature and schema immediately after creating the credential in MeetROAS.

5. Send production events

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

application/json
{
  "event_id": "test-9c8d0b15-4c87-49db-8c6e-6fcb80e0e39f",
  "mr_click_id": "mrc_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "event": "purchase",
  "occurred_at": "2026-08-10T17:01:59.042Z",
  "value": 49.95,
  "currency": "USD"
}
FieldRequiredFormat and semantics
event_idYesDestination-generated idempotency key, 1–128 characters, no personal data; preserve it for retries of the same business fact.
mr_click_idYesOpaque MeetROAS ID persisted from the destination URL.
eventYesMust be present in the accepted event catalog below.
occurred_atYesISO-8601 UTC; event time must be within 31 days.
valueOptional for monetary eventsDecimal amount from 0 to 1,000,000,000 with up to six decimals; not minor units and never converted by MeetROAS.
currencyOptionalUppercase ISO 4217 code; requires value. MeetROAS never guesses a currency.

Reusing an event_id with a different event, occurred_at, mr_click_id, value, or currency returns 409.

6. Accepted events

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

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
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
purchase
Purchase
A payment or purchase was verified and settled successfully; pending, failed, or refunded transactions do not qualify.repeatableUse a distinct ID per transaction and preserve it when retrying that transaction.Optional

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

7. Supported traffic platforms

The destination sends the same Partner Event API schema for every supported traffic platform and does not implement platform-specific postbacks.

StatusTraffic platformsNotes
SupportedTrafficStars, PropellerAds, RichAds, ExoClickThe customer configures the matching traffic-platform account and conversion goals in MeetROAS.
PlannedAdsterra, MGID, BidVertiser, HilltopAds, GeeMee, MGSkyAdsNot yet available as a supported production capability; do not plan a launch date around it.

8. Responses, retries, and go-live

HTTPMeaningAction
200Validation passed, or a production event is an already processed duplicateSuccess; do not mint a new event_id for the retry
202Production 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
404Production endpoint cannot resolve mr_click_idConfirm the real 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
  1. Obtain credentials and pass the validation endpoint.
  2. Send one production event using a real mr_click_id from a test visitor.
  3. Ask the customer account Admin to confirm the event in MeetROAS and complete traffic-platform configuration.
  4. After confirmation, begin sending production business events.

9. 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 credentials are lost or suspected to be exposed, the customer account Admin rotates them immediately. The old Key stops working at once.