RateUp Documentation

External API

Call RateUp from your own code — authentication, worked examples, and the full API reference.

The External API lets your own systems drive RateUp: create contacts, send WhatsApp templates, award loyalty points, pull survey responses.

It is a REST API over HTTPS, authenticated with a single API access key.

The full API reference lives at api.rateup.app/reference. Every endpoint, parameter, schema and response is there, generated from the API itself — so it is always current. This page covers how to authenticate and shows a few worked examples.


Getting an API Key

Go to Settings → Integrations and open API Service.

Click Generate Api Key. Before you generate one, the panel reads "No API Key Found".

Copy the key and the API Base URL shown beside it. You need both.

API access key management
ActionEffect
Generate Api KeyCreates a key for the organisation
RegenerateIssues a new key and invalidates the old one immediately
DeleteRevokes API access entirely

The key carries super-admin access to your whole organisation — every contact, conversation and loyalty balance. Treat it like a root password: never commit it to a repository, never ship it in front-end code, and regenerate immediately if it leaks.

Regenerate and Delete take effect at once. Any integration still using the old key starts failing with 401 the moment you click.


Base URL & Authentication

Every endpoint sits under a versioned path that includes your organisation id:

https://api.rateup.app/api/external/v1/{orgId}

The exact base URL, with your orgId already filled in, is shown on the API Access Key panel — copy it from there rather than assembling it by hand.

Send the key as a bearer token on every request:

curl "https://api.rateup.app/api/external/v1/$ORG_ID/contacts" \
  -H "Authorization: Bearer $RATEUP_API_KEY"

There is no session, no refresh and no expiry. The key is valid until you regenerate or delete it.


What You Can Do

The API covers contacts, contact groups, campaigns, WhatsApp templates, loyalty, surveys and teams.

See api.rateup.app/reference for the complete endpoint list with request and response schemas. Authorise once with your key and you can try any endpoint straight from the page.

The examples below cover the three requests people ask about most.

body_variables is optional. Send it only if the template's body contains variables — {{1}}, {{2}} and so on. A template with fixed wording needs no body_variables at all.

When you do send it, provide one entry per variable, in order. The header image and the body variables are independent: a template can have an image header and no variables, or variables and no header.


Example 1 · Send a Template with an Uploaded Image

Use POST /wa/templates/send-with-file when the image lives on your machine rather than at a public URL. The request is multipart/form-data; RateUp uploads the file to WhatsApp and attaches it as the template's header.

curl -X POST \
  "https://api.rateup.app/api/external/v1/$ORG_ID/wa/templates/send-with-file" \
  -H "Authorization: Bearer $RATEUP_API_KEY" \
  -F "templateName=order_shipped" \
  -F "phone=14155552671" \
  -F "headerType=image" \
  -F "file=@/path/to/banner.jpg" \
  -F 'body_variables=["Priya","8821"]'
FieldNotes
templateNameThe approved template's name
phoneIncluding country code, without +
headerTypeimage, video or document
fileThe binary file. Maximum 100 MB
filenameOptional; used for document headers
body_variablesOptional. A JSON-encoded array string, in template order — only if the body has variables
teamId, tagOptional — attribution and reporting
timeDelayOptional; schedules the send. Minimum 15

If the template's body has no variables, leave the field out entirely:

curl -X POST \
  "https://api.rateup.app/api/external/v1/$ORG_ID/wa/templates/send-with-file" \
  -H "Authorization: Bearer $RATEUP_API_KEY" \
  -F "templateName=new_menu_announcement" \
  -F "phone=14155552671" \
  -F "headerType=image" \
  -F "file=@/path/to/banner.jpg"

When you do send it, body_variables must be a JSON string in a multipart request — '["Priya","8821"]', not repeated form fields. Malformed JSON is silently treated as an empty array, so the variables vanish and the template sends with blanks.

When timeDelay is set, the response is { "status": ..., "scheduleId": ... } instead of the send result.


Example 2 · Send a Template with an Image by URL

If the image is already hosted publicly, use the JSON endpoint POST /wa/templates/send and pass a link — no upload needed.

curl -X POST \
  "https://api.rateup.app/api/external/v1/$ORG_ID/wa/templates/send" \
  -H "Authorization: Bearer $RATEUP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateName": "order_shipped",
    "phone": 14155552671,
    "parameterData": [
      { "type": "image", "link": "https://cdn.example.com/banner.jpg" }
    ],
    "body_variables": ["Priya", "8821"]
  }'
FieldNotes
phoneA number, with country code, no +
parameterData[].typeimage, video or document
parameterData[].linkMust be publicly reachable — WhatsApp fetches it
parameterData[].filenameOptional; for document headers
body_variablesOptional. A real JSON array here, not a string — only if the body has variables

A template whose body is fixed wording needs nothing more than the header:

{
  "templateName": "new_menu_announcement",
  "phone": 14155552671,
  "parameterData": [
    { "type": "image", "link": "https://cdn.example.com/banner.jpg" }
  ]
}

Prefer this form when you already host the asset — it is one request instead of an upload, and the same URL can be reused across sends. Use Example 1 when the file is generated on the fly, such as a per-order PDF.


Example 3 · Send an Authentication (OTP) Template

Authentication templates deliver a one-time code, usually with a copy code button.

curl -X POST \
  "https://api.rateup.app/api/external/v1/$ORG_ID/wa/templates/send" \
  -H "Authorization: Bearer $RATEUP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateName": "login_verification",
    "phone": 14155552671,
    "body_variables": ["482915"]
  }'

Pass the code once. For a template whose button is a copy-code button, RateUp reuses the first body variable as the button's value automatically. You do not send the OTP twice, and you should not set buttonVariable for it.

Building the template

The template itself is created under WhatsApp → Templates:

Choose the Authentication category.

Add an Authentication Button — only one is allowed per template.

Set the Code Expiration (minutes) so the message states how long the code lasts.

Submit it for approval. Nothing can be sent until WhatsApp approves it.

Checking it arrived

The send response includes a message id. Poll its status:

curl "https://api.rateup.app/api/external/v1/$ORG_ID/wa/templates/message/$MESSAGE_ID/status" \
  -H "Authorization: Bearer $RATEUP_API_KEY"

For OTP flows, prefer the message status webhook over polling — you find out about a failed delivery in time to offer the customer another route, instead of after they have given up.

Generate and expire OTPs in your system, not RateUp's. The API delivers the code; it does not validate it.


Errors

StatusBodyCause
400No bearer token found in headersThe Authorization header is missing or malformed
400Invalid phone number formatThe number is not valid for its country code
401No access token found in headersThe header says Bearer but carries no token
401Invalid access tokenThe key is wrong, or has been regenerated or deleted
404Not foundThe orgId is missing from the path
404Org with orgId='…' not foundThe orgId does not exist

A 404 here usually means a URL problem, not a missing record. If every endpoint returns 404, check the orgId segment of your base URL first.


Working With It

  • Store the key in a secret manager or environment variable — never in source control
  • Call it from your server, never from a browser or mobile app; the key cannot be scoped down
  • Handle 401 explicitly so a rotated key raises a clear alert rather than losing data quietly
  • Send phone numbers with the country code and no +, everywhere
  • Get templates approved before you need them — approval is not instant
  • Use webhooks for events and the API for actions; polling for something you could be told about is wasted effort

On this page