rcscheck.dev

API Reference

Validate RCS payloads programmatically. Integrate into CI/CD pipelines, ESP platforms, or internal tooling — without pasting JSON into a browser.

Base URL: https://rcscheck.dev/api/v1JSON onlyCORS enabled

Quick start

No API key needed to try it. Anonymous requests are rate-limited to 10/minute.

curl
curl -X POST https://rcscheck.dev/api/v1/validate \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
      "contentMessage": {
        "text": "Hello from RCS!",
        "fallback": { "text": "Hello!" }
      }
    },
    "aggregator": "google"
  }'
json
{
  "ok": true,
  "valid": true,
  "messageType": "text",
  "aggregator": "google",
  "summary": {
    "errors": 0,
    "warnings": 0,
    "info": 1,
    "passed": 30,
    "total": 31
  },
  "errors": [],
  "warnings": [],
  "info": [
    {
      "ruleId": "SUGG-010",
      "severity": "info",
      "description": "...",
      "path": "contentMessage.suggestions",
      "fix": "..."
    }
  ],
  "meta": {
    "validatedAt": "2026-05-31T10:00:00.000Z",
    "durationMs": 2,
    "apiVersion": "v1",
    "docs": "https://rcscheck.dev/api-docs"
  }
}

Authentication

Get a free API key to unlock higher rate limits. Pass it as a Bearer token or X-Api-Key header.

curl
# Get a free API key
curl -X POST https://rcscheck.dev/api/v1/keys \
  -H "Content-Type: application/json" \
  -d '{ "email": "you@company.com", "name": "My CI pipeline" }'

# Use the key
curl -X POST https://rcscheck.dev/api/v1/validate \
  -H "Authorization: Bearer rcs_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "payload": { ... }, "aggregator": "twilio" }'

⚠ API keys are shown once at creation and never retrievable again. Store them in environment variables or a secrets manager.

Rate limits

TierPer minutePer monthPrice
Anonymous10100Free
Free (API key)301,000Free
Pro12010,000$29/mo
Enterprise600UnlimitedCustom

Rate limit headers are returned on every response: X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Tier. On 429, check Retry-After.

POST /validate

POSThttps://rcscheck.dev/api/v1/validate

Validates an RCS payload against the GSMA spec and the selected aggregator's rules. Returns a full ValidationReport.

Request body

FieldTypeDescription
payloadrequiredobjectThe RCS contentMessage payload to validate. Must contain a contentMessage field.
aggregatorstringWhich aggregator rules to apply. One of: google, twilio, sinch, infobip. Defaults to "google".
strictbooleanIf true, warnings are treated as errors for the valid flag. Useful for CI/CD gates.

Response fields

FieldTypeDescription
okbooleantrue if the request succeeded (not the same as valid).
validbooleantrue if the payload passes all rules with no errors (or no warnings in strict mode).
messageTypestringInferred message type: text, richCard, carousel, or unknown.
aggregatorstringThe aggregator used for validation.
summaryobjectCounts of errors, warnings, info, passed, total rules evaluated.
errorsRuleViolation[]Rules that failed with severity: error.
warningsRuleViolation[]Rules that failed with severity: warning.
infoRuleViolation[]Informational rule notes.
metaobjectvalidatedAt (ISO 8601), durationMs, apiVersion.

POST /keys

POSThttps://rcscheck.dev/api/v1/keys

Request a free API key. One key per email address. The key is returned once in the response body.

FieldTypeDescription
emailrequiredstringYour email address. Used to identify your key. No spam — ever.
namestringA label for this key, e.g. "CI pipeline" or "Staging env".

Error codes

HTTPerror codeMeaning
400invalid_jsonRequest body is not valid JSON.
400invalid_requestRequest body is not a JSON object.
400missing_payloadThe payload field is missing from the request.
401invalid_api_keyThe API key is malformed or not found.
401api_key_revokedThe API key has been revoked.
409key_existsAn active API key already exists for this email.
429rate_limit_exceededToo many requests. Check Retry-After header.
500validator_errorInternal error. Please report via GitHub Issues.

Code examples

Node.js

javascript
const response = await fetch("https://rcscheck.dev/api/v1/validate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + process.env.RCSCHECK_API_KEY,
  },
  body: JSON.stringify({
    payload: myRcsPayload,
    aggregator: "google",
    strict: true,  // fail CI on warnings too
  }),
});

const result = await response.json();

if (!result.valid) {
  console.error("RCS payload is invalid:");
  result.errors.forEach((e) => {
    console.error(`  [${e.ruleId}] ${e.description}`);
    console.error(`  Fix: ${e.fix}`);
  });
  process.exit(1);
}

Python

python
import os, requests, sys

response = requests.post(
    "https://rcscheck.dev/api/v1/validate",
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {os.environ['RCSCHECK_API_KEY']}",
    },
    json={
        "payload": my_rcs_payload,
        "aggregator": "twilio",
        "strict": True,
    },
)

result = response.json()
if not result["valid"]:
    for error in result["errors"]:
        print(f"[{error['ruleId']}] {error['description']}")
        print(f"  Fix: {error['fix']}")
    sys.exit(1)

GitHub Actions CI

yaml
- name: Validate RCS payload
  run: |
    RESULT=$(curl -s -X POST https://rcscheck.dev/api/v1/validate \
      -H "Authorization: Bearer ${{ secrets.RCSCHECK_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d @rcs-payload.json)

    VALID=$(echo $RESULT | jq -r '.valid')
    if [ "$VALID" != "true" ]; then
      echo "RCS payload validation failed:"
      echo $RESULT | jq '.errors[]'
      exit 1
    fi

Database schema

Run the following migration in your Supabase SQL editor to enable API key storage.

sql
create table api_keys (
  id                   uuid primary key default gen_random_uuid(),
  key_hash             text unique not null,  -- SHA-256 of the full key
  key_prefix           text not null,          -- first 16 chars, safe to display
  name                 text not null,
  email                text not null,
  tier                 text not null default 'free',
  is_active            boolean not null default true,
  requests_this_month  integer not null default 0,
  created_at           timestamptz not null default now(),
  last_used_at         timestamptz,
  revoked_at           timestamptz
);

create index on api_keys (key_hash);
create index on api_keys (email);
alter table api_keys enable row level security;
create policy "Service role only" on api_keys
  for all using (auth.role() = 'service_role');
rcscheck.dev API v1Report an issue ↗