Getting Started
The SSN API lets approved clients create and manage sites, site visits, messages, file uploads, and webhook subscriptions through a tenant-scoped REST API.
This guide walks through the first successful integration path:
- Choose the correct environment.
- Request an access token.
- Create a site.
- Create a site visit for that site.
- Look up the visit by your ticket reference.
- Add a message.
Environments
Use sandbox while building and testing your integration.
| Environment | Base URL |
|---|---|
| Sandbox | https://sandbox-api.siteservicesnow.com/api/v1 |
| Production | https://api.siteservicesnow.com/api/v1 |
Sandbox and production use separate credentials. A token from one environment cannot be used against the other environment.
Credentials
SSN will provide a credential packet for each environment:
client_idclient_secret- allowed scopes
- valid
projectIdvalues - valid
itemNamevalues
Store the client secret securely. Do not send it in browser code or expose it in client-side applications.
Authentication
Use the OAuth2 client credentials flow.
POST /api/v1/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET
Successful response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "sites:read sites:write site-visits:read site-visits:write"
}
Send the token on API requests:
Authorization: Bearer YOUR_ACCESS_TOKEN
First API Check
Confirm your credential can read sites:
GET /api/v1/sites
Authorization: Bearer YOUR_ACCESS_TOKEN
An empty list is valid for a new client:
{
"data": [],
"meta": {
"pageSize": 25
}
}
Create a Site
Create a site using your own stable site identifier in siteCode.
POST /api/v1/sites
Authorization: Bearer YOUR_ACCESS_TOKEN
Idempotency-Key: 6d0c49d5-0a35-4c28-93e5-0ef6c8b04cd3
Content-Type: application/json
{
"name": "Demo Store 100",
"siteCode": "DEMO-STORE-100",
"addressLine1": "123 Main St",
"city": "Phoenix",
"stateRegion": "AZ",
"postalCode": "85001",
"country": "US"
}
Important rules:
siteCodemust be unique for your client account.- The API derives client ownership from your access token.
- Do not send a tenant ID or Quickbase record ID.
Create a Site Visit
Create a site visit by referencing the site through clientSiteId.
This value should match the siteCode from the site you created.
POST /api/v1/site-visits
Authorization: Bearer YOUR_ACCESS_TOKEN
Idempotency-Key: 0f7d1a6e-9642-41ba-aed5-77aa357c1ca6
Content-Type: application/json
{
"clientSiteId": "DEMO-STORE-100",
"description": "Replace damaged kiosk screen",
"clientTicketNumber": "CLIENT-TKT-10027",
"serviceType": "Break / Fix",
"jobInstructions": "Check in with store manager before opening the equipment.",
"projectId": 123,
"itemName": "TEST ITEM",
"startDate": "2026-04-15T16:00:00Z",
"dueDate": "2026-04-16T01:00:00Z",
"arePartsRequired": false,
"partsReturnRequired": false,
"schedulingRule": "Date/Time Specific"
}
Important rules:
clientSiteIdmust match a site owned by your client account.projectIdmust belong to your client account and be active.itemNamemust belong to your client account.clientTicketNumberis optional but should be unique for your client account.
Look Up a Site Visit by Client Ticket Number
If you supplied clientTicketNumber, you can use it to look up the visit later.
GET /api/v1/site-visits?clientTicketNumber=CLIENT-TKT-10027
Authorization: Bearer YOUR_ACCESS_TOKEN
Add a Message
Messages are created against an existing site visit.
POST /api/v1/messages
Authorization: Bearer YOUR_ACCESS_TOKEN
Idempotency-Key: 2a24d0e9-233c-42c7-a4a3-fd579debd8ad
Content-Type: application/json
{
"siteVisitId": "visit_0d995b97a85e4c64ad5594c2e74b69e4",
"type": "Support",
"messageThread": "Client note: technician should call before arrival.",
"status": "Open",
"urgency": "Normal",
"buyer": true,
"clientContacts": true
}
The API sets these values internally:
method = EmailoccurredAt = nowssnPm = true
Upload Files
Site-visit return labels:
POST /api/v1/site-visits/{id}/return-label
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: multipart/form-data
Message attachments:
POST /api/v1/messages/{id}/file-attachment
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: multipart/form-data
Use form field name file.
Supported file types:
- return labels: PDF
- message attachments: PDF, PNG, JPEG
Webhooks
Webhook delivery is available for clients with webhook scopes.
Current live event:
ticket.created
Webhook deliveries use an event envelope:
{
"id": "evt_...",
"type": "ticket.created",
"occurredAt": "2026-04-03T16:19:30.074Z",
"resourceType": "site-visits",
"resourceId": "visit_...",
"payloadVersion": "2026-03-24",
"data": {}
}
Clients should:
- verify the HMAC signature
- deduplicate by event ID
- respond with a 2xx status code when the event is accepted
Common Error Cases
| Status | Meaning |
|---|---|
401 | Missing or invalid bearer token |
403 | Credential does not have the required scope |
404 | Referenced client-owned site, project, item, or resource was not found |
409 | Duplicate resource or optimistic concurrency conflict |
422 | Request validation failed |
Next Steps
After this first path works in sandbox:
- Test duplicate-site behavior.
- Test invalid project and invalid item error handling.
- Test message creation and patching.
- Configure webhook delivery if your integration needs event notifications.
- Request production credentials when sandbox validation is complete.