Skip to main content

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:

  1. Choose the correct environment.
  2. Request an access token.
  3. Create a site.
  4. Create a site visit for that site.
  5. Look up the visit by your ticket reference.
  6. Add a message.

Environments

Use sandbox while building and testing your integration.

EnvironmentBase URL
Sandboxhttps://sandbox-api.siteservicesnow.com/api/v1
Productionhttps://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_id
  • client_secret
  • allowed scopes
  • valid projectId values
  • valid itemName values

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:

  • siteCode must 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:

  • clientSiteId must match a site owned by your client account.
  • projectId must belong to your client account and be active.
  • itemName must belong to your client account.
  • clientTicketNumber is 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 = Email
  • occurredAt = now
  • ssnPm = 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

StatusMeaning
401Missing or invalid bearer token
403Credential does not have the required scope
404Referenced client-owned site, project, item, or resource was not found
409Duplicate resource or optimistic concurrency conflict
422Request validation failed

Next Steps

After this first path works in sandbox:

  1. Test duplicate-site behavior.
  2. Test invalid project and invalid item error handling.
  3. Test message creation and patching.
  4. Configure webhook delivery if your integration needs event notifications.
  5. Request production credentials when sandbox validation is complete.