Documentation menu

Customer API

MeetROAS Customer API

Read performance and create or edit Apps and Campaigns with the complete Dashboard editor fields through the REST API.

1. Quickstart

Traffic buyer: Want your AI assistant to check ad performance?

  1. Go to Dashboard /account/api 's "API" tab to create a Key
  2. The complete Key is shown only once; immediately store it in an environment variable securely (e.g. read -rs MEETROAS_API_KEY then export MEETROAS_API_KEY, a password manager, or CI secrets)
  3. Copy the following command and run it directly; the shell expands the variable automatically
Quickstart example
curl https://open.meetroas.com/v1/me \
  -H "Authorization: Bearer $MEETROAS_API_KEY"

Developer: Need to integrate into your own service or script? Continue reading the REST API Reference below.

2. Authentication

Obtain API Key

  • In Dashboard /account/api 's "API" tab, create a new key
  • The complete Key is shown only once at creation, format: mrp_<id>_<secret>
  • Valid for 30/90/365 days, no permanent Keys
  • Maximum 5 valid Keys per creator, 20 per account

Usage

All REST requests require the Authorization header:

Authorization header
Authorization: Bearer mrp_<id>_<secret>

Scopes

Choose scopes explicitly when creating a Key; existing keys and the default selection remain read-only:

  • apps:read — Read app list
  • campaigns:read — Read campaigns
  • performance:read — Read performance data (including placement insights)
  • apps:write — Create and edit Apps; also requires apps:read
  • campaigns:write — Create and edit Campaigns; also requires apps:read and campaigns:read

Effective permissions = Key scopes ∩ creator's current role. Takes up to 10 seconds after the creator is disabled or demoted, revocation is immediate.

Security reminder

API Keys are equivalent to account credentials. Never paste the complete Key into any chat window, issue, screenshot, or source code; store it only in local config files or environment variables. If you suspect a leak, revoke it in the Dashboard and create a new one.

3. Quota and limits

Quota enforces both quota units and request counts independently. Each plan has both per-minute and daily limits:

Planunits/minuteunits/day (UTC)
Free301,000
Starter605,000
Pro12020,000
Scale300100,000

Unit costs

Callunits
GET /v1/me, GET /v1/apps, GET /v1/apps/{appSlug}/campaigns1
GET /v1/apps/{appSlug}/campaigns/{campaignId}/placement-insights10
GET /v1/.../editor, GET /v1/media/staging/{receipt}1
Create/edit App or Campaign, stage media5
GET /health, /openapi.json, /docs, /llms.txt0 (no authentication)

So the Free plan allows up to 3 placement insight calls per minute, 100 per day; general reads are 30 per minute, 1,000 per day.

Response headers

  • RateLimit-Limit — units limit per minute
  • RateLimit-Remaining — remaining units in rolling 60-second window
  • RateLimit-Reset — seconds until the oldest entry leaves the window
  • X-MeetROAS-Daily-Remaining — remaining units today
  • X-MeetROAS-Api-Version — 1

Other limits

  • GET /v1/apps does not paginate (plan limit is 30 Apps maximum)
  • Placement insights return up to 500 groups, remainder aggregated in other; 5000-row/CSV mode not available
  • CORS disabled, browser-side JavaScript cannot call directly

4. REST API Reference

Base URL: https://open.meetroas.com/v1

GET /v1/me

Required scopes: any valid Key · Quota units: 1

Get current API Key information, account plan, and remaining quota.

GET /v1/me
curl "https://open.meetroas.com/v1/me" \
  -H "Authorization: Bearer $MEETROAS_API_KEY"
Response
{
  "ok": true,
  "data": {
    "key": {
      "id": "a7f3k29d1mq4x8bz",
      "label": "My API Key",
      "scopes": ["apps:read", "campaigns:read", "performance:read"],
      "expiresAt": "2027-01-01T00:00:00Z"
    },
    "account": {
      "id": "acc_9f2c4d61-8b3a-4e57-9d10-2f6b8c1e4a77",
      "plan": "pro"
    },
    "creator": {
      "role": "admin"
    },
    "quota": {
      "perMinute": {
        "limit": 120,
        "remaining": 118,
        "resetInSeconds": 42
      },
      "daily": {
        "limit": 20000,
        "remaining": 15234
      }
    }
  }
}

GET /v1/apps

Required scopes: apps:read · Quota units: 1

Get all Apps in the account.

GET /v1/apps
curl "https://open.meetroas.com/v1/apps" \
  -H "Authorization: Bearer $MEETROAS_API_KEY"
Response
{
  "ok": true,
  "data": {
    "items": [
      {
        "id": "brand_4a7c9e21b8d35f60a1c4e7b209d63f8a",
        "slug": "my-game",
        "name": "My Awesome Game",
        "iconUrl": "https://assets.meetroas.com/icons/my-game.png",
        "trafficSource": {
          "id": "trafficstars",
          "label": "TrafficStars"
        },
        "campaignCount": 5,
        "reportingTimezone": "Asia/Taipei"
      }
    ]
  }
}

GET /v1/apps/{appSlug}/campaigns

Required scopes: apps:read + campaigns:read · Quota units: 1

Get all campaigns in the specified App.

GET /v1/apps/{appSlug}/campaigns
curl "https://open.meetroas.com/v1/apps/my-game/campaigns" \
  -H "Authorization: Bearer $MEETROAS_API_KEY"
Response
{
  "ok": true,
  "data": {
    "app": {
      "id": "brand_4a7c9e21b8d35f60a1c4e7b209d63f8a",
      "slug": "my-game",
      "name": "My Awesome Game"
    },
    "items": [
      {
        "id": "brand:brand_4a7c9e21b8d35f60a1c4e7b209d63f8a",
        "kind": "primary",
        "label": "My Awesome Game",
        "host": "my-game.meetroas.com",
        "enabled": true,
        "objective": "pwa_install",
        "trafficSource": {
          "id": "trafficstars",
          "label": "TrafficStars"
        }
      }
    ]
  }
}

GET /v1/apps/{appSlug}/campaigns/{campaignId}/placement-insights

Required scopes: apps:read + campaigns:read + performance:read · Quota units: 10

Get placement insights and recommendations for the specified campaign.

Query parameters:

  • range: today | 7d | 30d (default: 7d)
  • dimension: placement | subPlacement | creative | upstreamCampaign | country | environment (default: placement)
GET placement-insights
curl "https://open.meetroas.com/v1/apps/my-game/campaigns/brand:brand_9f2c41ab7d0e4c518a63b2d7e04f19c5/placement-insights?range=7d&dimension=placement" \
  -H "Authorization: Bearer $MEETROAS_API_KEY"

Response contains campaigns, totals, rows (up to 500), other, and advice (block, whitelist, bids, targeting), see https://open.meetroas.com/openapi.json

Create and edit Apps and Campaigns

All writes require Idempotency-Key (8–128 characters); PATCH also requires the If-Match ETag from the matching /editor GET. A stale version returns 412.

  • POST /v1/apps、PATCH /v1/apps/{appSlug}:JSON with the Dashboard App editor's content, primary, destination, objective and media sections.
  • POST /v1/apps/{appSlug}/campaigns、PATCH /v1/apps/{appSlug}/campaigns/{campaignId}:Multipart form with every Dashboard Campaign editor field; JSON {enabled:boolean} changes a secondary Campaign's status.
  • GET /v1/apps/{appSlug}/editor、GET /v1/apps/{appSlug}/campaigns/{campaignId}/editor:Get complete editable data and ETag. The primary Campaign uses App editor fields and apps:write.
  • POST /v1/media/staging:Stage icon, screenshots, hero or video, then use its receipt in the media field. On create, target is new-app:{Idempotency-Key} or new-page:{appId}:{Idempotency-Key}.

Request fields and JSON shapes are in https://open.meetroas.com/openapi.json

5. Errors and retries

HTTPMeaningHandling
401 invalid_api_keyKey invalid, revoked, expired, or account/creator disabledDo not retry; use a different Key
403 forbidden_scopeInsufficient scopesDo not retry; use a Key with sufficient scopes
404 not_foundApp slug or campaign id not foundUse /v1/apps, /v1/apps/{slug}/campaigns to get correct id
400 validation_failedParameter format error (e.g. range=14d)Fix parameters
409 conflict / idempotency_conflictPlan limit or creation key reused with different contentThe latter includes createdId for the resource already created
412 precondition_failedEditor snapshot changedReload /editor and its ETag
422 unprocessable_entityEditor field validation failedInspect fieldErrors
428 precondition_requiredEdit missing If-MatchFetch the /editor ETag first
429 rate_limited / quota_exceededunits or request count exceededWait per Retry-After
503 service_unavailableDependency temporarily unavailableWait per Retry-After
5xx (no Retry-After)Internal errorExponential backoff 2/4/8/16/32 sec + jitter, max 5 times

GET requests can be retried; keep the same Idempotency-Key for writes, and reload /editor and ETag after an edit conflict.

6. Differences from Partner Event API

FeaturePartner Event APICustomer API
AudienceDestination platform vendorsMeetROAS customers (traffic buyers) and their developers
Hostapi.meetroas.comopen.meetroas.com
Workermeetroas (Traffic)meetroas-api (new)
AuthenticationHMAC signature (Key ID + Secret + timestamp)Bearer token (API Key)
DirectionReceive conversion events (write)Read account and performance; manage Apps and Campaigns
Quota300 requests per Key per 60 secPlan-based units (Free: 30 units/min, 1,000 units/day)
OpenAPIdevelopers.meetroas.com/openapi.jsonopen.meetroas.com/openapi.json (Hub /api/openapi.json 307 redirect)

7. Phase 2 preview

GET /v1/apps Phase 1 does not paginate (plan limit 30 Apps). Phase 2 onwards, unlimited list endpoints support ?limit= (1–100, default 50) and opaque ?cursor=, response {items, nextCursor}.

OAuth 2.1 is planned for Phase 3.