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:
- obtain an OAuth token
- call
/api/core/whoami - retrieve assigned numbers
- send a first message using a Red Cloud
numberId - 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_123client_secret:rc_secret_abc123access_token:rc_token_examplenumberId:num_abc123messageId:msg_abc123externalReference:order_789phone:+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_123client_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
3600seconds - your integration must refresh tokens when they expire
Recommended implementation pattern
- 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_clientfailures 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
numberIdis the value you later send assendFromsendFromis not a phone number string- if you only remember one integration detail, remember that
sendFromis 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-Keyis 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-TimestampX-RedCloud-Signature
Common first-integration mistakes
- using the E.164 number where
sendFromexpectsnumberId - forgetting the
Idempotency-Keyheader - treating
QUEUEDas final delivery - not persisting
messageIdandexternalReference - accepting webhook payloads without signature verification
- debugging send behavior before confirming
/whoamiand/numbers
Integration callouts
sendFromis not a phone number. It is the Red CloudnumberId.Idempotency-Keyprevents accidental duplicate sends.- Webhooks are required for delivery lifecycle awareness.
- Tokens expire and must be refreshed.