Skip to main content

Getting Started

The Red Cloud CORE API lets an API client:

  • obtain an OAuth access token
  • inspect its current CORE identity
  • list assigned numbers
  • search available numbers
  • update number settings
  • queue outbound messages
  • receive customer-facing webhook events for message lifecycle and inbound traffic

This page is the shortest path to a first successful integration.

The five-step integration path

For almost every new integration, the correct startup sequence is:

  1. obtain an OAuth token
  2. call /api/core/whoami
  3. retrieve assigned numbers
  4. send a first message using a Red Cloud numberId
  5. confirm lifecycle delivery by webhook

If you skip that order, troubleshooting becomes harder because later failures are often caused by an earlier setup problem.

Canonical example values

These values are reused across the docs so examples stay deterministic for both humans and AI agents.

  • client_id: rc_test_client_123
  • client_secret: rc_secret_abc123
  • access_token: rc_token_example
  • numberId: num_abc123
  • messageId: msg_abc123
  • externalReference: order_789
  • phone: +15551234567

Step 1: Obtain API credentials

An API client authenticates with OAuth 2 client_credentials.

Conceptually, you need:

  • a client_id
  • a matching client_secret

For the examples below:

  • client_id = rc_test_client_123
  • client_secret = rc_secret_abc123

What this means

Your integration does not send an API key header on CORE API requests. It first exchanges client credentials for a bearer token, then uses that token on /api/core/* routes.

Operational note

Treat the client credentials as the root of trust for your integration. If token acquisition fails, do not continue to later steps until credential status is resolved.

Step 2: Get an access token

Request

curl -X POST "$BASE_URL/api/auth/token" \
-u "rc_test_client_123:rc_secret_abc123" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials"

Response

{
"access_token": "rc_token_example",
"token_type": "bearer",
"expires_in": 3600
}

What this means

  • the token is used as Authorization: Bearer rc_token_example
  • tokens expire after 3600 seconds
  • your integration must refresh tokens when they expire
  • cache the token with its expiry
  • refresh before expiry or immediately after a 401
  • retry the protected API call once after refreshing
  • do not retry invalid_client failures blindly

Step 3: Call /whoami

Request

curl "$BASE_URL/api/core/whoami" \
-H "Authorization: Bearer rc_token_example"

Response

{
"apiClientId": "rc_test_client_123",
"apiClientName": "Red Cloud Test Client",
"apiClientStatus": "ACTIVE",
"capabilities": [
"numbers:read",
"numbers:search",
"numbers:update"
],
"assignedNumbers": {
"total": 1,
"smsEnabledCount": 1,
"mmsEnabledCount": 1
},
"inboundWebhookConfigured": true,
"deliveryWebhookConfigured": true
}

What this means

This confirms:

  • the bearer token is valid
  • the API client is active
  • the client has assigned numbers available for later send operations

It also confirms whether webhook delivery is already configured from the platform side. That is useful before testing send lifecycle handling.

Step 4: Retrieve numbers

Request

curl "$BASE_URL/api/core/numbers" \
-H "Authorization: Bearer rc_token_example"

Response

{
"numbers": [
{
"numberId": "num_abc123",
"e164": "+15551234567",
"status": "ACTIVE",
"campaignRegId": "A1B2C3",
"smsEnabled": true,
"mmsEnabled": true,
"webhookInboundOverride": "https://example.com/webhooks/inbound",
"webhookDeliveryOverride": "https://example.com/webhooks/delivery"
}
]
}

What this means

  • numberId is the value you later send as sendFrom
  • sendFrom is not a phone number string
  • if you only remember one integration detail, remember that sendFrom is the Red Cloud number id

Practical consequence

Many first-send failures happen because teams pass the E.164 number instead of the Red Cloud numberId. Always store and reuse the numberId returned by the CORE API.

Step 5: Send your first message

Request

curl -X POST "$BASE_URL/api/core/messages/send" \
-H "Authorization: Bearer rc_token_example" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: idem_order_789" \
-d '{
"sendFrom": "num_abc123",
"to": ["+15551234567"],
"messageType": "SMS",
"text": "Hello from Red Cloud",
"externalReference": "order_789"
}'

Response

{
"results": [
{
"to": "+15551234567",
"messageId": "msg_abc123",
"status": "QUEUED"
}
],
"errors": []
}

What this means

  • Idempotency-Key is required
  • the message is queued, not synchronously delivered
  • idempotency prevents duplicate sends when you retry the same request safely

Operational consequence

The synchronous send response is an acceptance response, not final delivery proof. The delivery lifecycle continues asynchronously by webhook.

Step 6: Receive webhooks

Red Cloud webhook delivery is the lifecycle channel for:

  • outbound status changes
  • inbound customer messages

Example outbound webhook

{
"eventType": "message.delivery",
"direction": "outbound",
"occurredAt": 1775002218105,
"apiClientId": "rc_test_client_123",
"messageId": "msg_abc123",
"sequence": 3,
"data": {
"messageId": "msg_abc123",
"externalReference": "order_789",
"sendFrom": "+15551234567",
"to": "+15551234567",
"status": "delivered",
"error": null
}
}

What this means

  • webhooks are the delivery lifecycle mechanism
  • they are not optional if you want reliable downstream status handling
  • signature verification should use:
    • X-RedCloud-Timestamp
    • X-RedCloud-Signature

Common first-integration mistakes

  • using the E.164 number where sendFrom expects numberId
  • forgetting the Idempotency-Key header
  • treating QUEUED as final delivery
  • not persisting messageId and externalReference
  • accepting webhook payloads without signature verification
  • debugging send behavior before confirming /whoami and /numbers

Integration callouts

  • sendFrom is not a phone number. It is the Red Cloud numberId.
  • Idempotency-Key prevents accidental duplicate sends.
  • Webhooks are required for delivery lifecycle awareness.
  • Tokens expire and must be refreshed.