REST API Overview¶
The CX Platform REST API provides programmatic access to customer management, scheduling, communication channels, and more. Any language or tool that can make HTTP requests can integrate with the platform.
This page covers the fundamental concepts you need before making your first request.
Base URL¶
All partner API requests are made relative to the /cx/v2/ base path on your
environment-specific host:
https://cx2-main.pit.cxgp.us/cx/v2/
Environment-Specific URL
Use the environment host that matches your credentials.
A Test environment is maintained for integration and partner testing at https://cx2-main.pit.cxgp.us
and the Production URL will be provided by your representative. See
Authentication & Environments
for details.
Versioned Paths
New REST integrations should call explicit versioned URLs such as
/cx/v2/.... See API Versioning for migration and
compatibility guidance.
Authentication¶
The CX Platform API uses API Key authentication. Include your key in the
CX-API-KEY request header on every call:
curl -X POST "https://cx2-main.pit.cxgp.us/cx/v2/action/setCustomer" \
-H "CX-API-KEY: $CX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"givenName": "Ol",
"familyName": "Persson",
"primaryEmail": {
"value": "ol.persson@example.com"
}
}'
import com.gp.cx.sdk.api.CustomersApi;
import com.gp.cx.sdk.client.CxSdkClient;
import com.gp.cx.sdk.exceptions.CxSdkClientException;
import com.gp.cx.sdk.model.ChannelEmailDTO;
import com.gp.cx.sdk.model.CustomerDTO;
CxSdkClient client = new CxSdkClient.Builder()
.apiKey(System.getenv("CX_API_KEY"))
.baseUrl("https://cx2-main.pit.cxgp.us")
.build();
CustomersApi customersApi = client.getCustomersApi();
CustomerDTO payload = new CustomerDTO()
.givenName("Ol")
.familyName("Persson")
.primaryEmail(new ChannelEmailDTO().value("ol.persson@example.com"));
try {
CustomerDTO created = customersApi.setCustomer(payload);
System.out.println(created.getDisplayCustomerId());
} catch (CxSdkClientException e) {
System.err.println("Error " + e.getStatusCode() + ": " + e.getApiErrorMessage());
}
import os
import requests
url = "https://cx2-main.pit.cxgp.us/cx/v2/action/setCustomer"
headers = {
"CX-API-KEY": os.environ["CX_API_KEY"],
"Content-Type": "application/json",
}
payload = {
"givenName": "Ol",
"familyName": "Persson",
"primaryEmail": {"value": "ol.persson@example.com"},
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
print(response.json())
const response = await fetch(
"https://cx2-main.pit.cxgp.us/cx/v2/action/setCustomer",
{
method: "POST",
headers: {
"CX-API-KEY": process.env.CX_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
givenName: "Ol",
familyName: "Persson",
primaryEmail: { value: "ol.persson@example.com" },
}),
}
);
if (!response.ok) {
const err = await response.json();
throw new Error(err.message);
}
const data = await response.json();
console.log(data);
using System.Net.Http;
using System.Net.Http.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add(
"CX-API-KEY",
Environment.GetEnvironmentVariable("CX_API_KEY")
);
var payload = new
{
givenName = "Ol",
familyName = "Persson",
primaryEmail = new { value = "ol.persson@example.com" }
};
var response = await client.PostAsJsonAsync(
"https://cx2-main.pit.cxgp.us/cx/v2/action/setCustomer",
payload
);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<object>();
Console.WriteLine(result);
Store your key in an environment variable
All examples above read CX_API_KEY from the environment.
See Security Best Practices
for guidance on protecting your API keys.
This example assumes you are using a Location API key and have already called
POST /cx/v2/action/setServiceLocation for that location key.
API Key Hierarchy¶
API keys exist at two permission levels. Each level inherits the permissions of the levels below it:
┌────────────────────────────────┐
│ Implementation Key │ ← Scoped to one implementation
│ (Can generate Location keys) │
├────────────────────────────────┤
│ Location Key │ ← Scoped to one service location
│ (Most restrictive) │
└────────────────────────────────┘
| Key Level | Scope | Typical Use |
|---|---|---|
| Implementation | Single implementation | Integration setup, key management |
| Location | Single service location | Day-to-day API operations |
Generating Keys
Use POST /cx/v2/apikey with an Implementation-level key to
generate Location-level API keys programmatically.
Common Request Headers¶
The following headers apply to every API request:
| Header | Required | Example Value | Description |
|---|---|---|---|
CX-API-KEY |
Required | YOUR_API_KEY |
Authenticates the request. Must match the scope of the resource being accessed. |
Content-Type |
Required for POST/PUT/PATCH | application/json |
Declares the request body format. All request bodies must be JSON. |
Accept |
Optional | application/json |
Preferred response format. JSON is returned by default; this header can be omitted. |
CORS Policy¶
The CX Platform API is designed for server-to-server communication. CORS headers are not enabled for arbitrary browser origins, so calling the API directly from browser JavaScript will be blocked by the browser's same-origin policy.
Do not call the API from browser JavaScript
Doing so would also expose your CX-API-KEY in client-side code, where it
is visible to any user. API keys must be kept server-side.
Recommended pattern for browser-based clients:
Browser → Your Backend Server → CX Platform API
Route all CX API calls through a server-side component (e.g., a REST controller,
serverless function, or API gateway). Your backend holds the CX-API-KEY in a
secure environment variable and proxies only the data your frontend needs.
Request Format¶
All request bodies must be JSON. Set the following headers on every request:
Content-Type: application/json
CX-API-KEY: YOUR_API_KEY
Common Partner Onboarding Flow¶
For partner integrations, the verified sequence is:
- Receive an Implementation API key from CX Support.
- Call
POST /cx/v2/apikeywith that Implementation key to generate a Location API key. - Call
POST /cx/v2/action/setServiceLocationwith the generated Location key. - Use that same Location key for downstream location-scoped API calls such as
POST /cx/v2/action/setCustomer, payment requests, statements, scheduling, and other service-location operations.
Response Format¶
All successful responses return JSON. Error responses use a consistent structure:
{
"message": "Human-readable error description"
}
Error Body
The error response contains a single message field describing what went
wrong. Always check the HTTP status code and the message body when
handling errors.
Amount Handling¶
All monetary amounts are represented as integers in the smallest currency unit (e.g., cents for USD). This avoids floating-point precision issues.
| Display Amount | API Value | Currency |
|---|---|---|
| $50.00 | 5000 |
USD |
| $12.50 | 1250 |
CAD |
Supported currencies currently include USD, & CAD.
Date and Time Format¶
All date and time values use ISO-8601 format:
2025-06-15T14:30:00Z
Timestamps are in UTC unless otherwise specified.
Core Resources¶
The API is organized around the following primary resources:
| Resource | Description | Key Endpoints |
|---|---|---|
| Customers | Create/update and retrieve customer records | POST /cx/v2/action/setCustomer, GET /cx/v2/customer/{id} |
| Service Locations | Manage physical service locations | POST /cx/v2/action/setServiceLocation, GET /cx/v2/serviceLocation |
| Statements | Create or update customer statements | POST /cx/v2/action/setStatement |
| Events | Create, query, and cancel scheduling events | POST /cx/v2/action/setEvent, GET /cx/v2/scheduling/event, POST /cx/v2/action/cancelEvent |
| Payment Requests | Create payment requests for customer collections workflows | POST /cx/v2/action/createPaymentRequest |
| Quotes | Create customer-facing service quotes | POST /cx/v2/action/createQuote |
HTTP Status Codes¶
| Code | Meaning | When Returned |
|---|---|---|
| 200 | OK | Successful GET, PUT, PATCH, or DELETE |
| 201 | Created | Successful POST that creates a new resource |
| 400 | Bad Request | Validation errors, malformed input, declined payments |
| 401 | Unauthorized | Missing, invalid, or expired API key |
| 403 | Forbidden | Valid key but insufficient permissions for this operation |
| 404 | Not Found | Requested resource does not exist |
| 409 | Conflict | Database conflict (e.g., duplicate unique constraint) |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server-side failure |
Rate Limiting¶
The API enforces rate limits to ensure fair usage. When you exceed the limit, the API returns a 429 Too Many Requests response.
Handling 429 Responses
Implement exponential back-off with jitter in your client to handle rate limit responses gracefully. Wait progressively longer between retries.
Pagination¶
Some list endpoints support pagination via query parameters. Check individual endpoint documentation for supported pagination options.