Introduction
Sweep&Go - Open API description
This documentation aims to provide all the information you need to work with our API.
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
You can retrieve your token by visiting your dashboard and clicking Generate API token.
Access token
Endpoints for generating, retrieving, and managing API access tokens.
An access token authenticates an integration against the Open API (/api/v1 and /api/v2) and also defines the webhook URL and the webhook events that are delivered for the organization. These endpoints are used internally by the Sweep&Go application (Settings > Open API) and are not intended for AI assistants or for answering business questions about clients, jobs or billing. To inspect the token currently in use, see "Show access token details" (GET /api/v2/check_token).
List API access tokens
Returns all API access tokens for the given organization, including masked token values, webhook URLs, and enabled events, plus the list of all webhook events that can be enabled.
Internal endpoint used by the Sweep&Go application to manage Open API integrations — not intended for AI assistants or end users. Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/token_generate/access_tokens?organization_id=2"const url = new URL(
"https://openapi.sweepandgo.com/api/token_generate/access_tokens"
);
const params = {
"organization_id": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
fetch(url, {
method: "GET",
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/token_generate/access_tokens';
$response = $client->get(
$url,
[
'query' => [
'organization_id' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/token_generate/access_tokens'
params = {
'organization_id': '2',
}
response = requests.request('GET', url, params=params)
response.json()Example response (200):
[
{
"data": [
{
"id": 12,
"token": "************************************************************XLtm",
"webhooks_url": "https://example.com/webhooks",
"description": "First token",
"enabled_events": [
"client:client_onboarding_onetime",
"client:client_recurring_employee_portal"
]
},
{
"id": 18,
"token": "************************************************************9P4a",
"webhooks_url": "https://example.com/webhooks",
"description": "Second token",
"enabled_events": [
"client:client_onboarding_onetime"
]
}
],
"webhooks": {
"free:quote": "Free quote",
"lead:out_of_service_area": "Lead - out of service area",
"lead:in_service_area": "Lead - in service area",
"lead:delete": "Lead - deleted",
"client:changed_status": "Client - changed status",
"client:changed_info": "Client - changed info",
"client:changed_address": "Client - changed address",
"client:client_onboarding_recurring": "Client - client onboarding recurring",
"client:client_onboarding_onetime": "Client - client onboarding onetime",
"client:subscription_created": "Client - subscription created",
"client:subscription_canceled": "Client - subscription canceled",
"client:subscription_paused": "Client - subscription paused",
"client:subscription_unpaused": "Client - subscription unpaused",
"client:invoice_finalized": "Client - invoice finalized",
"client:client_no_assigned": "Client - client no assigned",
"client:client_assigned": "Client - client assigned",
"client:subscription_cancel_requested": "Client - subscription cancel requested",
"client:notification_settings_changed": "Client - notification settings changed",
"client:additional_contact_changed": "Client - additional contact changed",
"client:client_payment_declined": "Client - client payment declined",
"client:client_payment_accepted": "Client - client payment accepted",
"client:reviews_automation": "Client - reviews automation",
"client:areas_to_clean_changed": "Client - areas to clean changed",
"notification:on_the_way_notification": "Notification - on the way notification",
"notification:off_schedule_notification": "Notification - off schedule notification",
"notification:completed_job_notification": "Notification - completed job notification",
"notification:skipped_job_notification": "Notification - skipped job notification",
"notification:client_not_assigned": "Notification - Client not assigned",
"staff:staff_clock_in": "Staff - staff clock in",
"staff:staff_forgot_to_clock_out": "Staff - staff forgot to clock out",
"staff:shift_break_started": "Staff - shift break started",
"staff:shift_break_info": "Staff - shift break info",
"job:started": "Job - started with info",
"job:completed": "Job - completed with info start time, end time, job type and price",
"organization:client_onboarding_form_changed": "Business - client onboarding form changed",
"organization:cross_sells_changed": "Business - cross sells changed",
"payroll:shift_info": "Payroll - shift info, work time, start time, end time, mileages, duration, break duration",
"payroll:tip_info": "Payroll - tip linked to invoice with amount",
"dog:birthday": "Send webhook on dog birthday 7 days in advance",
"client:credit_card_link_created": "Private credit card link created for add new credit card"
}
}
]
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get API access token details
Returns a masked version of an API access token (only the last characters are visible) together with its ID.
Internal endpoint used by the Sweep&Go application to manage Open API integrations — not intended for AI assistants or end users. Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/token_generate/access_token/12"const url = new URL(
"https://openapi.sweepandgo.com/api/token_generate/access_token/12"
);
fetch(url, {
method: "GET",
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/token_generate/access_token/12';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/token_generate/access_token/12'
response = requests.request('GET', url, )
response.json()Example response (200):
{
"token": "lrLxIj3PmNkSKdsFdTYYrfLFSungwVl4vXUk9alQo3Zu6cCGpslCGfHI9k2wXLtm",
"_id": 12
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Generate API access token
requires authentication
Creates a new API access token for the given organization, with its webhook URL and enabled webhook events. The full token value is returned only in this response.
Internal endpoint used by the Sweep&Go application to manage Open API integrations — not intended for AI assistants or end users. This is a write operation: it creates a new credential that grants API access to the organization's data.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/token_generate/access_token" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"organization_id\": 2,
\"webhooks_url\": \"https:\\/\\/example.com\\/webhooks\",
\"enabled_events\": [
\"fugit\"
],
\"description\": \"Webhooks for client onboarding events\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/token_generate/access_token"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"organization_id": 2,
"webhooks_url": "https:\/\/example.com\/webhooks",
"enabled_events": [
"fugit"
],
"description": "Webhooks for client onboarding events"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/token_generate/access_token';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'organization_id' => 2,
'webhooks_url' => 'https://example.com/webhooks',
'enabled_events' => ['fugit'],
'description' => 'Webhooks for client onboarding events',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/token_generate/access_token'
payload = {
"organization_id": 2,
"webhooks_url": "https:\/\/example.com\/webhooks",
"enabled_events": [
"fugit"
],
"description": "Webhooks for client onboarding events"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"token": "lrLxIj3PmNkSKdsFdTYYrfLFSungwVl4vXUk9alQo3Zu6cCGpslCGfHI9k2wXLtm",
"_id": 12
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete API access token
requires authentication
Deletes (revokes) an API access token. The token must belong to the organization of the caller; integrations using it immediately lose API access and stop receiving webhooks.
Internal endpoint used by the Sweep&Go application to manage Open API integrations — not intended for AI assistants or end users. This is a destructive write operation.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/token_generate/access_token/12/delete" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/token_generate/access_token/12/delete"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/token_generate/access_token/12/delete';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/token_generate/access_token/12/delete'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Tests
Endpoints for testing connectivity, authentication and API availability.
These endpoints do not return any business data (clients, jobs, invoices, reports) and should only be used to verify that the API is reachable and the access token is valid.
API health check
Returns the current status of the API. This endpoint can be used by monitoring services to verify that the API is running and reachable.
Does not require an access token and does not validate one — to check that a token is valid use "Test v2 API endpoint" (GET /api/v2/welcome) or "Show access token details" (GET /api/v2/check_token). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/health"const url = new URL(
"https://openapi.sweepandgo.com/api/health"
);
fetch(url, {
method: "GET",
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/health';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/health'
response = requests.request('GET', url, )
response.json()Example response (200):
{
"status": "OK",
"version": "v1"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Test v1 API endpoint
requires authentication
Echoes back the received request payload and sends a test:request webhook to the organization's webhook URL.
Use this only to verify that the API token is valid and the v1 API is reachable, or to test webhook delivery. It returns no business data — do not use it to answer questions about clients, jobs or billing. For a test without the webhook side effect use "Test v2 API endpoint" (GET /api/v2/welcome).
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/welcome" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/welcome"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/welcome';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/welcome'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"success": "v1",
"request": {
"example_param": "example_value"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Test v2 API endpoint
requires authentication
Echoes back the received request payload, confirming that the v2 API is reachable and the access token is accepted.
Use this only to test connectivity or authentication (e.g. "is my API token working?"). It does not return any business data and has no side effects. Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/welcome" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/welcome"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/welcome';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/welcome'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"success": "v2",
"request": {
"example_param": "example_value"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Clients list
Endpoints for listing, searching and inspecting residential clients within the organization tied to the API token. Each client is identified by a unique client string (e.g. rcl_MTPQPRUUUY7G), which is returned by the list and search endpoints and is required by "Get client details and payments". Use the list endpoints to browse clients by status, the search endpoints to find a specific client by name or email, and the details endpoint to get a single client's payment history. For commercial (business) clients and their locations use the "Commercial clients list" endpoints instead.
Get active clients
requires authentication
Returns a paginated list of all active residential clients in the organization, including contact details, address, subscription names, service days, assigned field tech and notification preferences. Read-only.
Use this when the user wants to browse or export all currently active (serviced) residential clients.
Do not use this to find one specific client — use "Search clients by name" (GET /api/v1/clients/search_by_name)
or "Search client by email" (POST /api/v2/clients/client_search) instead. To list only active clients that have
no subscription use "Get active clients without an active subscription" (GET /api/v1/clients/active_no_subscription).
To count active clients without fetching them use "Count active clients" (GET /api/v2/report/count_active_clients).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/clients/active?page=2&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/clients/active"
);
const params = {
"page": "2",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/clients/active';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/clients/active'
params = {
'page': '2',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "rcl_MTPQPRUUUY7G",
"status": "active",
"type": "employee_portal",
"email": "demo@mail.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"subscription_names": "2w-3d,Deodorising",
"one_time_client": false,
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"tracking_field": "utm_campaign=blog_post &utm_medium=social&utm_source=facebook",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get active clients without an active subscription
requires authentication
Returns a paginated list of residential clients whose status is active but who have no subscription assigned
(empty subscription_names). Read-only.
Use this when the user wants to find active clients that are not on any recurring plan, e.g. to follow up,
upsell a subscription or clean up data. For all active clients use "Get active clients" (GET /api/v1/clients/active).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/clients/active_no_subscription?page=2&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/clients/active_no_subscription"
);
const params = {
"page": "2",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/clients/active_no_subscription';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/clients/active_no_subscription'
params = {
'page': '2',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "rcl_MTPQPRUUUY7G",
"status": "active",
"type": "employee_portal",
"email": "demo@mail.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"subscription_names": "2w-3d,Deodorising",
"one_time_client": false,
"tracking_field": "utm_campaign=blog_post &utm_medium=social&utm_source=facebook",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get inactive clients
requires authentication
Returns a paginated list of inactive (former or paused) residential clients in the organization. Read-only.
Use this when the user asks about former, cancelled or churned clients, e.g. for win-back campaigns.
For currently serviced clients use "Get active clients" (GET /api/v1/clients/active).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/clients/inactive?page=2&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/clients/inactive"
);
const params = {
"page": "2",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/clients/inactive';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/clients/inactive'
params = {
'page': '2',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "rcl_MTPQPRUUUY7G",
"status": "inactive",
"type": "employee_portal",
"email": "demo@mail.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"subscription_names": "",
"one_time_client": false,
"tracking_field": "utm_campaign=blog_post &utm_medium=social&utm_source=facebook",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Search clients by name
requires authentication
Returns a paginated list of residential clients (both active and inactive) whose first name, last name, "first last" or "last first" full name starts with the search term. Read-only.
The search is a prefix match. For example, "Jo" and "John" match "John Doe", "Doe John" also matches, but "ohn" does not.
Use this when the user refers to a client by name and you need the client's identifier (e.g. rcl_MTPQPRUUUY7G) or basic details. If you know the client's email, prefer "Search client by email" (POST /api/v2/clients/client_search). Once you have the client identifier, use "Get client details and payments" (POST /api/v2/clients/client_details) for payment history. For commercial clients use "Search commercial clients" (POST /api/v2/commercial_clients/search).
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/clients/search_by_name?search=John+Doe&page=1&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/clients/search_by_name"
);
const params = {
"search": "John Doe",
"page": "1",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/clients/search_by_name';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'search' => 'John Doe',
'page' => '1',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/clients/search_by_name'
params = {
'search': 'John Doe',
'page': '1',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "rcl_MTPQPRUUUY7G",
"status": "active",
"type": "employee_portal",
"email": "john.doe@example.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"city": "Davenport",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2026-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"subscription_names": "2w-3d, Deodorising",
"one_time_client": false,
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"tracking_field": "utm_campaign=blog_post&utm_medium=social",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get client details and payments
requires authentication
Returns a single residential client's details (contact info, address, status, subscriptions, service days, assigned field tech, notification and marketing preferences) together with the client's full payment history. Read-only.
Use this when the user asks about a specific client's payments, what a client paid, or needs full details of one client. Requires the client identifier (e.g. rcl_MTPQPRUUUY7G) — obtain it first via "Search clients by name" (GET /api/v1/clients/search_by_name), "Search client by email" (POST /api/v2/clients/client_search) or the client list endpoints. For payments across all clients use "Get payments" (GET /api/v2/payments). For commercial clients use "Get commercial client details" (POST /api/v2/commercial_clients/client_details).
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/clients/client_details" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"client\": \"rcl_MTPQPRUUUY7G\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/clients/client_details"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"client": "rcl_MTPQPRUUUY7G"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/clients/client_details';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'client' => 'rcl_MTPQPRUUUY7G',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/clients/client_details'
payload = {
"client": "rcl_MTPQPRUUUY7G"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"client": "rcl_MTPQPRUUUY7G",
"status": "active",
"type": "employee_portal",
"email": "demo@mail.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"tracking_field": "utm_campaign=blog_post &utm_medium=social&utm_source=facebook",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week",
"subscription_names": "2d1W",
"sum_payments": 10,
"payments": [
{
"id": 1049219,
"date": "2024-05-01",
"amount": 139.43,
"tip_amount": "5.00",
"status": "succeeded",
"type": "credit_card",
"description": "Payment for invoice(s) 199-66362-240501-2-1294170",
"created_at": "2024-05-01 11:19:38"
},
{
"id": 1048709,
"date": "2024-05-01",
"amount": 139.43,
"tip_amount": "0.00",
"status": "failed",
"type": "credit_card",
"description": "Payment for invoice(s) 199-66362-240501-2-1294170",
"created_at": "2024-05-01 11:11:13"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Search client by email
requires authentication
Finds a single residential client by exact email address and returns the client's details, including the client identifier (e.g. rcl_MTPQPRUUUY7G). Returns 403 with an empty body when no client matches. Read-only.
Use this when the user provides a client's email, or to check whether an email belongs to an existing client.
If several clients share the same email, use status and/or latest to pick the right one.
To search by name use "Search clients by name" (GET /api/v1/clients/search_by_name).
For payment history use "Get client details and payments" (POST /api/v2/clients/client_details).
During onboarding, to only check whether an active client with this email exists, use "Check client email exists" (GET /api/v2/client_on_boarding/check_client_email_exists).
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/clients/client_search" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"email\": \"john@doe.com\",
\"status\": \"active\",
\"latest\": true
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/clients/client_search"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "john@doe.com",
"status": "active",
"latest": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/clients/client_search';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'email' => 'john@doe.com',
'status' => 'active',
'latest' => true,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/clients/client_search'
payload = {
"email": "john@doe.com",
"status": "active",
"latest": true
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"client": "rcl_MTPQPRUUUY7G",
"status": "active",
"type": "employee_portal",
"email": "john@doe.com",
"first_name": "John",
"last_name": "Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"tracking_field": "utm_campaign=blog_post &utm_medium=social&utm_source=facebook",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "once_a_week",
"subscription_names": "2d1W"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding new clients
Endpoints for creating (onboarding) new residential clients in the organization's account. These are write operations: they create a client, subscription and, if a card token is provided, a credit card on file. Before calling them, use the Onboarding form endpoints to check the ZIP code, get the price/packages and form fields, validate a coupon and check that the email is not already a client.
Onboard a new residential client in Sweep&Go
requires authentication
Registers a new residential client in Sweep&Go.
This endpoint accepts client details, service preferences, notifications, dog information and optional payment details.
This is a write operation: it creates the client and their recurring (or one-time) cleanup subscription. Without credit_card_token the client is created with check payment.
Use this when the user asks to sign up / add / onboard a new residential client for regular dog waste cleanup priced by number of dogs and frequency. Do not use this for package-based signups — use Create client with package subscription (POST /api/v2/client_on_boarding/create_client_with_package) — and do not use it for out of area prospects — use Save out of service area lead (POST /api/v2/client_on_boarding/out_of_service_form). Returns HTTP 409 if an active client with the same email already exists and HTTP 429 if the same email is submitted again within a minute. Prerequisites: Check zip code exists in your account; allowed values for fields are available from Get onboarding form fields... (GET /api/v2/client_on_boarding/service_registration_form).
Example request:
curl --request PUT \
"https://openapi.sweepandgo.com/api/v1/residential/onboarding" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"zip_code\": \"12110\",
\"number_of_dogs\": 2,
\"last_time_yard_was_thoroughly_cleaned\": \"one_week\",
\"clean_up_frequency\": \"once_a_week\",
\"first_name\": \"John\",
\"last_name\": \"Doe\",
\"email\": \"mail@email.com\",
\"city\": \"Latham\",
\"home_address\": \"1494 Ben Street\",
\"state\": \"TX\",
\"areas_to_clean\": \"Front Yard, Back Yard\",
\"home_phone_number\": \"4155550110\",
\"cell_phone_number\": \"2025550101\",
\"initial_cleanup_required\": 1,
\"cleanup_notification_type\": \"on_the_way,completed\",
\"cleanup_notification_channel\": \"sms\",
\"how_heard_about_us\": \"social_media\",
\"how_heard_answer\": \"Facebook\",
\"additional_comment\": \"Please clean my yard.\",
\"credit_card_token\": \"tok_5678967890678 or 678987678909876\",
\"name_on_card\": \"John Doe\",
\"postal\": \"28301\",
\"expiry\": \"0924\",
\"dog_name\": [
\"ea\"
],
\"safe_dog\": [
\"minima\"
],
\"dog_breed\": [
\"at\"
],
\"dog_comment\": [
\"deserunt\"
],
\"cross_sells\": [
1,
2,
5
],
\"cross_sells_names\": \"Spraying,Trash bags,Premium Cleanup\",
\"coupon_code\": \"5pr1nG\",
\"marketing_allowed\": 1,
\"marketing_allowed_source\": \"open_api\",
\"gated_community\": \"67890\",
\"gate_location\": \"left\",
\"gate_code\": \"1234\",
\"tracking_field\": \"utm_campaign=blog_post&utm_medium=social&utm_source=facebook\",
\"terms_open_api\": 1
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v1/residential/onboarding"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"zip_code": "12110",
"number_of_dogs": 2,
"last_time_yard_was_thoroughly_cleaned": "one_week",
"clean_up_frequency": "once_a_week",
"first_name": "John",
"last_name": "Doe",
"email": "mail@email.com",
"city": "Latham",
"home_address": "1494 Ben Street",
"state": "TX",
"areas_to_clean": "Front Yard, Back Yard",
"home_phone_number": "4155550110",
"cell_phone_number": "2025550101",
"initial_cleanup_required": 1,
"cleanup_notification_type": "on_the_way,completed",
"cleanup_notification_channel": "sms",
"how_heard_about_us": "social_media",
"how_heard_answer": "Facebook",
"additional_comment": "Please clean my yard.",
"credit_card_token": "tok_5678967890678 or 678987678909876",
"name_on_card": "John Doe",
"postal": "28301",
"expiry": "0924",
"dog_name": [
"ea"
],
"safe_dog": [
"minima"
],
"dog_breed": [
"at"
],
"dog_comment": [
"deserunt"
],
"cross_sells": [
1,
2,
5
],
"cross_sells_names": "Spraying,Trash bags,Premium Cleanup",
"coupon_code": "5pr1nG",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api",
"gated_community": "67890",
"gate_location": "left",
"gate_code": "1234",
"tracking_field": "utm_campaign=blog_post&utm_medium=social&utm_source=facebook",
"terms_open_api": 1
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/residential/onboarding';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'zip_code' => '12110',
'number_of_dogs' => 2,
'last_time_yard_was_thoroughly_cleaned' => 'one_week',
'clean_up_frequency' => 'once_a_week',
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'mail@email.com',
'city' => 'Latham',
'home_address' => '1494 Ben Street',
'state' => 'TX',
'areas_to_clean' => 'Front Yard, Back Yard',
'home_phone_number' => '4155550110',
'cell_phone_number' => '2025550101',
'initial_cleanup_required' => 1,
'cleanup_notification_type' => 'on_the_way,completed',
'cleanup_notification_channel' => 'sms',
'how_heard_about_us' => 'social_media',
'how_heard_answer' => 'Facebook',
'additional_comment' => 'Please clean my yard.',
'credit_card_token' => 'tok_5678967890678 or 678987678909876',
'name_on_card' => 'John Doe',
'postal' => '28301',
'expiry' => '0924',
'dog_name' => ['ea'],
'safe_dog' => ['minima'],
'dog_breed' => ['at'],
'dog_comment' => ['deserunt'],
'cross_sells' => [1, 2, 5],
'cross_sells_names' => 'Spraying,Trash bags,Premium Cleanup',
'coupon_code' => '5pr1nG',
'marketing_allowed' => 1,
'marketing_allowed_source' => 'open_api',
'gated_community' => '67890',
'gate_location' => 'left',
'gate_code' => '1234',
'tracking_field' => 'utm_campaign=blog_post&utm_medium=social&utm_source=facebook',
'terms_open_api' => 1,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/residential/onboarding'
payload = {
"zip_code": "12110",
"number_of_dogs": 2,
"last_time_yard_was_thoroughly_cleaned": "one_week",
"clean_up_frequency": "once_a_week",
"first_name": "John",
"last_name": "Doe",
"email": "mail@email.com",
"city": "Latham",
"home_address": "1494 Ben Street",
"state": "TX",
"areas_to_clean": "Front Yard, Back Yard",
"home_phone_number": "4155550110",
"cell_phone_number": "2025550101",
"initial_cleanup_required": 1,
"cleanup_notification_type": "on_the_way,completed",
"cleanup_notification_channel": "sms",
"how_heard_about_us": "social_media",
"how_heard_answer": "Facebook",
"additional_comment": "Please clean my yard.",
"credit_card_token": "tok_5678967890678 or 678987678909876",
"name_on_card": "John Doe",
"postal": "28301",
"expiry": "0924",
"dog_name": [
"ea"
],
"safe_dog": [
"minima"
],
"dog_breed": [
"at"
],
"dog_comment": [
"deserunt"
],
"cross_sells": [
1,
2,
5
],
"cross_sells_names": "Spraying,Trash bags,Premium Cleanup",
"coupon_code": "5pr1nG",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api",
"gated_community": "67890",
"gate_location": "left",
"gate_code": "1234",
"tracking_field": "utm_campaign=blog_post&utm_medium=social&utm_source=facebook",
"terms_open_api": 1
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create client with package subscription
requires authentication
Creates a new residential client subscribed to a selected packaged cross-sell (service package).
This is a write operation: it creates the client and the package subscription. Without credit_card_token the client is created with check payment.
Use this when the client chooses one of the organization's packages.
Get cross_sell_id, category and billing_interval from Get packaged cross-sells (GET /api/v2/packages_list).
Do not use this for regular signups priced by number of dogs and frequency — use Onboard a new residential client in Sweep&Go (PUT /api/v1/residential/onboarding) instead.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/create_client_with_package" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"email\": \"john@doe.com\",
\"first_name\": \"John\",
\"last_name\": \"Doe\",
\"home_phone_number\": \"4155550110\",
\"cell_phone_number\": \"2025550101\",
\"home_address\": \"1502 Morse St\",
\"city\": \"New York\",
\"state\": \"TX\",
\"zip_code\": \"12345\",
\"clean_up_frequency\": \"once_a_week\",
\"cross_sell_id\": \"2\",
\"category\": \"cleanup\",
\"billing_interval\": \"monthly\",
\"credit_card_token\": \"tok_5678967890678 or 678987678909876\",
\"name_on_card\": \"John Doe\",
\"postal\": \"28301\",
\"expiry\": \"0924\",
\"cleanup_notification_type\": \"on_the_way,completed\",
\"cleanup_notification_channel\": \"sms\",
\"how_heard_about_us\": \"social_media\",
\"how_heard_answer\": \"Facebook\",
\"gated_community\": \"67890\",
\"gate_location\": \"left\",
\"gate_code\": \"1234\",
\"tracking_field\": \"utm_campaign=blog_post&utm_medium=social&utm_source=facebook\",
\"marketing_allowed\": 1,
\"marketing_allowed_source\": \"open_api\",
\"coupon_code\": \"5pr1nG\",
\"terms_open_api\": 1,
\"cross_sells_names\": \"Awesome package\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/create_client_with_package"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "john@doe.com",
"first_name": "John",
"last_name": "Doe",
"home_phone_number": "4155550110",
"cell_phone_number": "2025550101",
"home_address": "1502 Morse St",
"city": "New York",
"state": "TX",
"zip_code": "12345",
"clean_up_frequency": "once_a_week",
"cross_sell_id": "2",
"category": "cleanup",
"billing_interval": "monthly",
"credit_card_token": "tok_5678967890678 or 678987678909876",
"name_on_card": "John Doe",
"postal": "28301",
"expiry": "0924",
"cleanup_notification_type": "on_the_way,completed",
"cleanup_notification_channel": "sms",
"how_heard_about_us": "social_media",
"how_heard_answer": "Facebook",
"gated_community": "67890",
"gate_location": "left",
"gate_code": "1234",
"tracking_field": "utm_campaign=blog_post&utm_medium=social&utm_source=facebook",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api",
"coupon_code": "5pr1nG",
"terms_open_api": 1,
"cross_sells_names": "Awesome package"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/create_client_with_package';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'email' => 'john@doe.com',
'first_name' => 'John',
'last_name' => 'Doe',
'home_phone_number' => '4155550110',
'cell_phone_number' => '2025550101',
'home_address' => '1502 Morse St',
'city' => 'New York',
'state' => 'TX',
'zip_code' => '12345',
'clean_up_frequency' => 'once_a_week',
'cross_sell_id' => '2',
'category' => 'cleanup',
'billing_interval' => 'monthly',
'credit_card_token' => 'tok_5678967890678 or 678987678909876',
'name_on_card' => 'John Doe',
'postal' => '28301',
'expiry' => '0924',
'cleanup_notification_type' => 'on_the_way,completed',
'cleanup_notification_channel' => 'sms',
'how_heard_about_us' => 'social_media',
'how_heard_answer' => 'Facebook',
'gated_community' => '67890',
'gate_location' => 'left',
'gate_code' => '1234',
'tracking_field' => 'utm_campaign=blog_post&utm_medium=social&utm_source=facebook',
'marketing_allowed' => 1,
'marketing_allowed_source' => 'open_api',
'coupon_code' => '5pr1nG',
'terms_open_api' => 1,
'cross_sells_names' => 'Awesome package',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/create_client_with_package'
payload = {
"email": "john@doe.com",
"first_name": "John",
"last_name": "Doe",
"home_phone_number": "4155550110",
"cell_phone_number": "2025550101",
"home_address": "1502 Morse St",
"city": "New York",
"state": "TX",
"zip_code": "12345",
"clean_up_frequency": "once_a_week",
"cross_sell_id": "2",
"category": "cleanup",
"billing_interval": "monthly",
"credit_card_token": "tok_5678967890678 or 678987678909876",
"name_on_card": "John Doe",
"postal": "28301",
"expiry": "0924",
"cleanup_notification_type": "on_the_way,completed",
"cleanup_notification_channel": "sms",
"how_heard_about_us": "social_media",
"how_heard_answer": "Facebook",
"gated_community": "67890",
"gate_location": "left",
"gate_code": "1234",
"tracking_field": "utm_campaign=blog_post&utm_medium=social&utm_source=facebook",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api",
"coupon_code": "5pr1nG",
"terms_open_api": 1,
"cross_sells_names": "Awesome package"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Leads list
Endpoints for retrieving leads (prospects who are not yet clients) within the organization tied to the API token. Leads are identified by a lead string (e.g. rld_MTPQPRUUUY7G) and come from sources such as the onboarding form or the out-of-service-area form. Use "Get leads" for all leads and "Get out of area leads" for prospects whose address is outside the service area. For existing clients use the "Clients list" endpoints, and for free quote requests use "Get free quotes".
Get leads
requires authentication
Returns a paginated list of all leads in the organization, regardless of status or source, with contact details, address, lead type/source and marketing consent. Read-only.
Use this when the user asks about prospects, potential customers or sign-ups that did not become clients.
To get only leads outside the service area use "Get out of area leads" (GET /api/v1/leads/out_of_service).
For existing customers use "Get active clients" (GET /api/v1/clients/active); for quote requests use "Get free quotes" (GET /api/v2/free_quotes).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/leads/list?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/leads/list"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/leads/list';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/leads/list'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"lead": "rld_MTPQPRUUUY7G",
"status": "active",
"type": "onboarding_form",
"email": "demo@mail.com",
"name": "John Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get out of area leads
requires authentication
Returns a paginated list of leads whose address is outside the organization's service area (typically submitted through the out-of-service-area form). Read-only.
Use this when the user asks about prospects outside the service area, e.g. to evaluate expanding coverage.
For all leads use "Get leads" (GET /api/v1/leads/list).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/leads/out_of_service?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/leads/out_of_service"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/leads/out_of_service';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/leads/out_of_service'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"lead": "rld_MTPQPRUUUY7G",
"status": "lead",
"type": "out_of_area",
"email": "demo@mail.com",
"name": "John Doe",
"address": "3289 Summit Street",
"zip_code": "52801",
"home_phone": null,
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api"
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 10,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Dispatch Board
Endpoints for retrieving the daily job schedule (the Dispatch Board) for the organization tied to the API token. A job is a single scheduled cleanup visit for a residential client location or a commercial location, with its type, status, assigned field tech, price and address. Use this group for per-day schedules; for aggregated or per-employee reports use the "Reports" endpoints (e.g. "Route planning report", "Completed jobs report").
Get Dispatch Board jobs for a date
requires authentication
Returns all jobs on the Dispatch Board for a single date — both residential and commercial (commercial = 1),
dispatched and not yet dispatched — with job type, status, assigned field tech, estimated time, price, address,
coordinates, gate/dog info and the client's phone, email and marketing consent. Read-only. Not paginated.
Use this when the user asks what jobs/cleanups are scheduled for a given day, who is assigned to which job, or which jobs on a date are pending, completed, skipped or missed. For a list of only completed jobs over a date range use "Completed jobs report" (GET /api/v2/report/completed_jobs_report); for per-employee routes use "Route planning report" (GET /api/v2/report/route_planning_report); for a simple count use "Count completed jobs" (GET /api/v2/report/jobs_count).
Notes:
- A job with
id> 0 represents an already dispatched job record. - A job with
id= 0 represents an undispatched job.
Supported job status values:
- pending (1)
- completed (2)
- skipped (3)
- missed (4)
- started (5)
- dispatched (6)
Supported job types:
- custom
- initial
- one_time
- reclean
- recurring
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/dispatch_board/jobs_for_date?date=2022-03-28" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/dispatch_board/jobs_for_date"
);
const params = {
"date": "2022-03-28",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/dispatch_board/jobs_for_date';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'date' => '2022-03-28',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/dispatch_board/jobs_for_date'
params = {
'date': '2022-03-28',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"id": 0,
"client_location_id": 2603,
"client_id": null,
"commercial_location_id": 142,
"commercial_client_id": 84,
"pricing_plan_name": "Pet waste stations",
"commercial": 1,
"full_name": "Little Lambs Foundation for Kids",
"address": "1011 W 400 N",
"city": "Logan",
"zip": "84321",
"state_name": "Utah",
"clean_up_frequency": "1xW",
"count_cross_sells": 1,
"price": "25.00",
"quantity": 1,
"assigned_to_name": "Bart Cage",
"assigned_to_id": 265,
"estimate_time": "00:15",
"type": "recurring",
"end_time": null,
"start_time": null,
"status_id": 1,
"status_name": "pending",
"duration": "-",
"gate_code": null,
"gated_community": null,
"lat": 41.7389868,
"lng": -111.860119,
"number_of_dogs": null,
"safe_dogs": null,
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"email": "demo@demo.com"
},
{
"id": 0,
"client_location_id": 2726,
"client_id": 1580,
"commercial_location_id": null,
"commercial_client_id": null,
"pricing_plan_name": "Regular Plan",
"commercial": 0,
"full_name": "Cara Deen",
"address": "625 South 100 West",
"city": "Garland",
"zip": "84312",
"state_name": "Utah",
"clean_up_frequency": "two_times_a_week",
"count_cross_sells": 0,
"price": "25.00",
"quantity": 1,
"assigned_to_name": "Richard Dawson",
"assigned_to_id": 258,
"estimate_time": "00:15",
"type": "recurring",
"end_time": null,
"start_time": null,
"status_id": 1,
"status_name": "pending",
"duration": "-",
"gate_code": null,
"gated_community": null,
"lat": 41.7344582,
"lng": -112.1634671,
"number_of_dogs": 2,
"safe_dogs": "",
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"email": "demo@demo.com"
},
{
"id": 156608,
"client_location_id": 2325,
"type": "recurring",
"organization_id": 158,
"client_id": null,
"full_name": "Community Garden",
"address": "468 1/2 S 200 W",
"city": "Logan",
"zip": "84321",
"state_name": "Utah",
"assigned_to_id": 265,
"assigned_to_name": "Bart Cage",
"end_time": null,
"start_time": null,
"status_id": 6,
"lat": 41.7228185,
"lng": -111.8397648,
"estimate_time": "00:15",
"job_image": null,
"image_for_client": null,
"note": null,
"note_for_client": null,
"order": 1,
"arrival": 4,
"distance": "3.00",
"skip_reason_title": null,
"gate_code": null,
"count_cross_sells": 1,
"price": "25.00",
"quantity": 1,
"number_of_dogs": null,
"safe_dogs": null,
"gated_community": null,
"commercial": 1,
"work_areas": null,
"commercial_client_id": 76,
"commercial_location_id": 127,
"start_lat": null,
"start_lng": null,
"start_distance": null,
"clean_up_frequency": null,
"end_lat": null,
"end_lng": null,
"end_distance": null,
"skip_lat": null,
"skip_lng": null,
"skip_distance": null,
"status_name": "dispatched",
"duration": "-",
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"email": "demo@demo.com"
},
{
"id": 156890,
"client_location_id": 2578,
"type": "custom",
"organization_id": 158,
"client_id": 1567,
"full_name": "Carolina Wozniacki",
"address": "149 W 300 N",
"city": "Logan",
"zip": "84321",
"state_name": "Utah",
"assigned_to_id": 246,
"assigned_to_name": "Ena Adamz",
"end_time": "2022-03-29 08:24:07",
"start_time": "2022-03-29 08:22:08",
"status_id": 2,
"lat": 41.7374576,
"lng": -111.8385534,
"estimate_time": "00:15",
"job_image": null,
"image_for_client": null,
"note": "",
"note_for_client": "",
"order": 5,
"arrival": null,
"distance": null,
"skip_reason_title": null,
"gate_code": null,
"count_cross_sells": 0,
"number_of_dogs": 1,
"safe_dogs": "",
"gated_community": null,
"commercial": 0,
"work_areas": null,
"commercial_client_id": null,
"commercial_location_id": null,
"start_lat": null,
"start_lng": null,
"start_distance": null,
"clean_up_frequency": "bi_weekly",
"price": "25.00",
"quantity": 1,
"end_lat": null,
"end_lng": null,
"end_distance": null,
"skip_lat": null,
"skip_lng": null,
"skip_distance": null,
"status_name": "completed",
"duration": "00:21",
"home_phone": "4155550110",
"cell_phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api",
"email": "demo@demo.com"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Access token checker
Endpoints for retrieving API access token details.
Use this to verify a token and see which webhook URL and webhook events are configured for it. Token management (create, list, delete) is handled by the internal "Access token" endpoints.
Show access token details
requires authentication
Returns the webhook URL, the enabled webhook events and the internal ID of the given API access token.
Use this when the user asks "which webhooks are enabled for my integration", "where are webhooks sent", or to verify that a token is valid (an invalid token returns 404). It does not return client, job or billing data. To see webhooks that have actually been triggered, use "List triggered webhooks" (GET /api/v1/webhooks/list). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/check_token?token=vUcSxeEgTgg0I65bPEgKBqU0AjBRz8cy61843egzKkI3hAcYJ9ErNYe2MTEoIEWo" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/check_token"
);
const params = {
"token": "vUcSxeEgTgg0I65bPEgKBqU0AjBRz8cy61843egzKkI3hAcYJ9ErNYe2MTEoIEWo",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/check_token';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'token' => 'vUcSxeEgTgg0I65bPEgKBqU0AjBRz8cy61843egzKkI3hAcYJ9ErNYe2MTEoIEWo',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/check_token'
params = {
'token': 'vUcSxeEgTgg0I65bPEgKBqU0AjBRz8cy61843egzKkI3hAcYJ9ErNYe2MTEoIEWo',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"webhooks_url": "https://example.com/webhooks",
"enabled_events": "[\"lead:in_service_area\",\"lead:delete\",\"client:changed_status\"]",
"_id": 1
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Multi organization zip code check
Endpoints for multi-location businesses and integrations (e.g. the WordPress plugin) that work with several Sweep&Go organizations. Use them to route a prospect to the right organization by ZIP code and to verify that an organization has premium access. All endpoints are read-only.
Find the nearest eligible organization for a ZIP code
requires authentication
Read-only. Use this when a business operates several organizations (locations) and you need to decide which one should serve a prospect's ZIP code, e.g. "which of our locations covers ZIP 12345?". Do not use this for a single organization — use Check zip code exists in your account (POST /api/v2/client_on_boarding/check_zip_code_exists) instead.
Returns the registration URL and the selected organization slug based on the provided ZIP code and a list of organization slugs.
If the ZIP code is not in any service area, the nearest organization is returned and out_of_area will be 1.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/check_zip_code_multi_organizations?zip_code=12345&slugs[]=assumenda" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/check_zip_code_multi_organizations"
);
const params = {
"zip_code": "12345",
"slugs[0]": "assumenda",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/check_zip_code_multi_organizations';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'zip_code' => '12345',
'slugs[0]' => 'assumenda',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/check_zip_code_multi_organizations'
params = {
'zip_code': '12345',
'slugs[0]': 'assumenda',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"url": "https://google.com",
"slug": "ena-adamz-midmc",
"out_of_area": 1
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check whether an organization is premium
requires authentication
Returns whether the authenticated organization is premium (valid) and its name. Only premium organizations have access to the WordPress plugin. Read-only.
Use this when you need to verify that the organization may use the WordPress plugin or other premium-only integrations. Do not use this for general organization details — use Get organization branding info (GET /api/v2/client_on_boarding/organization_data) instead.
Onboarding form
The client onboarding workflow helps dog owners get a free quote and sign up for residential service on their own. These endpoints are read-only helpers (plus one lead-capture endpoint) used to build a custom signup form, website widget or chat flow for the authenticated organization.
Typical order of calls: check the ZIP code (Check zip code exists in your account) → if in area, get the price (Get price, tax percent, cross sells...) and the form fields (Get onboarding form fields...) → optionally get the default coupon / validate a coupon code and check whether the email is already a client → create the client with Onboard a new residential client in Sweep&Go (PUT /api/v1/residential/onboarding) → show the thank you message (Get thank you messages...). If the ZIP code is out of area, get the out of area form fields and submit them with Save out of service area lead (POST /api/v2/client_on_boarding/out_of_service_form).
Each account has its own unique and prebuilt client onboarding url which you may want to use as a reference. To obtain your url, please visit Employee portal > Settings > Client Onboarding > View in Browser then copy the url shown in the address bar. The form should look like this: https://client.sweepandgo.com/unique-slug/register
Get price, tax percent, cross sells, cross sells placement, custom price and more
requires authentication
Returns a residential service price quote for the organization: the recurring price (value, billing category and interval), tax percent, custom initial/one-time price text, price display options and the list of cross-sells (additional services) with their placement. Read-only; nothing is saved and no quote/lead is created.
Use this when the user asks how much service costs, e.g. "how much is weekly cleanup for 2 dogs in ZIP 12345 if the yard was last cleaned a month ago?", or before onboarding a client to show them the price. Call Check zip code exists in your account (POST /api/v2/client_on_boarding/check_zip_code_exists) first; pricing is only available for ZIP codes inside the service area. Do not use this to list packaged cross-sells (packages) — use Get packaged cross-sells (GET /api/v2/packages_list) instead.
If the zip code is within the account service area, you may obtain price based on account (organization) slug, number of dogs, zip code, cleanup frequency and the last time the yard was cleaned.
If the initial and one time cleanup prices do not depend on the number of dogs and when the yard was cleaned last time, the account may set custom prices.
The regular price can be displayed per cleanup or as fixed price per default billing interval. To choose how to display your pricing on your client onboarding form go to Employee Portal > Settings > Billing > Onboarding Price display section > Edit > select price display option > Save.
The account special offers and important disclaimers may be highlighted within the price display. To update them go to Settings > Client Onboarding > Callouts & Disclaimers.
If the account offers additional services such as odor eliminator or kitty litter exchange you may also display those prices on the client onboarding form. To add additional services, go to Employee Portal > Settings > Additional Services > Add New.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/price_registration_form?last_time_yard_was_thoroughly_cleaned=one_week&clean_up_frequency=once_a_week&number_of_dogs=2&zip_code=12345" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/price_registration_form"
);
const params = {
"last_time_yard_was_thoroughly_cleaned": "one_week",
"clean_up_frequency": "once_a_week",
"number_of_dogs": "2",
"zip_code": "12345",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/price_registration_form';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'last_time_yard_was_thoroughly_cleaned' => 'one_week',
'clean_up_frequency' => 'once_a_week',
'number_of_dogs' => '2',
'zip_code' => '12345',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/price_registration_form'
params = {
'last_time_yard_was_thoroughly_cleaned': 'one_week',
'clean_up_frequency': 'once_a_week',
'number_of_dogs': '2',
'zip_code': '12345',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"price": {
"value": "85.00",
"category": "prepaid",
"billing_interval": "monthly"
},
"tax_percent": "10.250",
"tax_percent_others": 1,
"pricing_zip_code_type": "regular",
"custom_price": {
"short_description": "title",
"long_description": "desc"
},
"show_price_options": {
"show_per_cleanup": 1,
"show_per_billing_interval": 1,
"default_billing_interval": "monthly"
},
"cross_sells": [
{
"id": 1,
"name": "Deodorizing",
"description": "Eliminate poop and urine smell!",
"unit": "Monthly Treatment (up to 1/4 acre)",
"unit_amount": "39.99",
"taxable": 1,
"service": 1,
"tax_percent": "0.000",
"count_clients": 28
},
{
"id": 2,
"name": "Kitty Litter Exchange",
"description": null,
"unit": "1",
"unit_amount": "20.00",
"taxable": 0,
"service": 0,
"tax_percent": "0.000",
"count_clients": 2
},
{
"id": 3,
"name": "Dog Walking",
"description": null,
"unit": "15",
"unit_amount": "30.00",
"taxable": 0,
"service": 1,
"tax_percent": "0.000",
"count_clients": 1
},
{
"id": 4,
"name": "Yard Size XL",
"description": "3/4 Acre Surcharge",
"unit": "Monthly",
"unit_amount": "30.00",
"taxable": 0,
"service": 1,
"tax_percent": "0.000",
"count_clients": 0
},
{
"id": 5,
"name": "Yard Size XXL",
"description": "1 Acre Surcharge",
"unit": "Monthly",
"unit_amount": "40.00",
"taxable": 0,
"service": 1,
"tax_percent": "0.000",
"count_clients": 0
},
{
"id": 6,
"name": "Front Yard",
"description": null,
"unit": "Weekly",
"unit_amount": "10.00",
"taxable": 0,
"service": 1,
"tax_percent": "0.000",
"count_clients": 1
},
{
"id": 7,
"name": "Front Yard",
"description": null,
"unit": "Monthly",
"unit_amount": "40.00",
"taxable": 0,
"service": 1,
"tax_percent": "0.000",
"count_clients": 0
}
],
"cross_sells_placement": "top"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get onboarding form fields, terms of use, callout and disclaimer and list of states
requires authentication
Returns the organization's signup form configuration: the list of form fields (slug, label, type, step, whether it is required/shown for one-time and recurring clients, and allowed values), terms of use, callout and disclaimer texts, and the list of US states. The length of the signup form and the fields to fill out depend on your signup form settings. Read-only.
Use this when you need to know which fields (and which allowed values) are required to onboard a client, e.g. before calling Onboard a new residential client in Sweep&Go (PUT /api/v1/residential/onboarding), or when the user asks for the terms of service. Do not use this for prices — use Get price, tax percent, cross sells... (GET /api/v2/client_on_boarding/price_registration_form) instead.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/service_registration_form" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/service_registration_form"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/service_registration_form';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/service_registration_form'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"form_fields": [
{
"value": "",
"required": false,
"step": 2,
"frontend_name": "Coupon Code",
"frontend_type": "textfield",
"slug": "coupon_code",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "1,2,3,4,5",
"required": true,
"step": 2,
"frontend_name": "Number Of Dogs",
"frontend_type": "select_single",
"slug": "number_of_dogs",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "two_times_a_week,once_a_week,bi_weekly,once_a_month,one_time",
"required": true,
"step": 2,
"frontend_name": "Cleanup Frequency",
"frontend_type": "select_single",
"slug": "clean_up_frequency",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "one_week,two_weeks,three_weeks,one_month,two_months,3-4_months,5-6_months,7-9_months,10+_months",
"required": true,
"step": 2,
"frontend_name": "Last Time Yard Was Thoroughly Cleaned",
"frontend_type": "select_single",
"slug": "last_time_yard_was_thoroughly_cleaned",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "First Name",
"frontend_type": "textfield",
"slug": "first_name",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Last Name",
"frontend_type": "textfield",
"slug": "last_name",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Your Email Address",
"frontend_type": "textfield",
"slug": "your_email_address",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Confirm Email Address",
"frontend_type": "textfield",
"slug": "confirm_email_address",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": false,
"step": 3,
"frontend_name": "Home Phone Number",
"frontend_type": "textfield",
"slug": "home_phone_number",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Cell Phone Number",
"frontend_type": "textfield",
"slug": "cell_phone_number",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Home Address",
"frontend_type": "textfield",
"slug": "home_address",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "City",
"frontend_type": "textfield",
"slug": "city",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "State",
"frontend_type": "state",
"slug": "state_province_region",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": false,
"step": 3,
"frontend_name": "Dogs Name",
"frontend_type": "textfield",
"slug": "dogs_name",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "yes,no",
"required": true,
"step": 3,
"frontend_name": "Is it safe for us to be in the yard with your dog?",
"frontend_type": "select_single",
"slug": "safe_dog",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": false,
"step": 3,
"frontend_name": "Breed",
"frontend_type": "textfield",
"slug": "dogs_breeds",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": false,
"frontend_description": ""
},
{
"value": "",
"required": false,
"step": 3,
"frontend_name": "Additional comment for dog",
"frontend_type": "textfield",
"slug": "comments_for_each_dog",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "left,right,alley,no_gate,other",
"required": true,
"step": 3,
"frontend_name": "Where is your gate located?",
"frontend_type": "select_single",
"slug": "gate_location",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": true,
"step": 3,
"frontend_name": "Gated community",
"frontend_type": "textfield",
"slug": "gated_community",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": "Please insert the code if any"
},
{
"value": "Back Yard,Flower Beds,Deck/Patio,Dog Run,Garden,Side Yard (Left),Side Yard (Right),Area with Mulch,Area with Rocks",
"required": true,
"step": 3,
"frontend_name": "Which areas should we clean?",
"frontend_type": "select_multiple",
"slug": "areas_to_clean",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "off_schedule,on_the_way,completed",
"required": true,
"step": 3,
"frontend_name": "Cleanup Notifications",
"frontend_type": "select_multiple",
"slug": "cleanup_notification_type",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": "What cleanup message would you like to receive?"
},
{
"value": "email,sms,call",
"required": false,
"step": 3,
"frontend_name": "Notification Type",
"frontend_type": "select_single",
"slug": "cleanup_notification_chanel",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": "How would you like to receive cleanup notifications?"
},
{
"value": "credit_card,check",
"required": true,
"step": 3,
"frontend_name": "Please select your payment method",
"frontend_type": "select_single",
"slug": "payment_method",
"organization_form_id": 289,
"one_time": false,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "search_engine,previous_client,referred_by_family_or_friend,directory_listing,social_media,vehicle_signage,radio_ad,local_event,gift_certificate,other",
"required": true,
"step": 3,
"frontend_name": "Please tell us how you heard about us",
"frontend_type": "select_single",
"slug": "how_heard_about_us",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
},
{
"value": "",
"required": false,
"step": 3,
"frontend_name": "Additional comments",
"frontend_type": "textfield",
"slug": "additional_comment",
"organization_form_id": 289,
"one_time": true,
"recurring": true,
"show": true,
"frontend_description": ""
}
],
"terms_of_use": {
"content": "<p>As the client, you are responsible for maintaining safe access into and out of the yard (if we are unable to clean due to access, you will be charged for that cleanup), immediate notification of any changes in the number of pets and prompt payment of balances due.</p><p><br></p><p>Inclement weather may make it hazardous or impossible to make a scheduled cleanup. In this event, we will be responsible for servicing your yard as soon as possible.</p><p><br></p><p>If for any reason your pet(s) will not be using the yard for a certain period (i.e. vacation, illness, etc.) and you do not wish to be charged for an unnecessary visit(s), please let us know in advance to pause the service. </p><p><br></p><p>We assume no liabilities for damages to yards, gates, pets or other properties.</p><p><br></p><p>Fees and Promotions are subject to change at any time. In this rare circumstance, you will be notified at least two (2) weeks prior to any changes.</p><p><br></p><p>Either party may terminate service (in writing) at any time. Unpaid balances are due within 15 days.</p><p><br></p><p>By initiating service, both parties agree to the above terms and responsibilities.</p>"
},
"callout_disclaimer": {
"callout": "Our Best Rate! You and Your pet will love our service.",
"disclaimer": "We do not offer refunds for missed cleanups due to holidays, snow days or thunderstorms - Displayed pricing is for an average backyard up to an 1/8 of an acre - A valid credit card on file is required for recurring service."
},
"states": [
{
"id": 1,
"name": "Alabama - AL"
},
{
"id": 2,
"name": "Alaska - AK"
},
{
"id": 3,
"name": "Arizona - AZ"
},
{
"id": 4,
"name": "Arkansas - AR"
},
{
"id": 5,
"name": "California - CA"
},
{
"id": 6,
"name": "Colorado - CO"
},
{
"id": 7,
"name": "Connecticut - CT"
},
{
"id": 8,
"name": "Delaware - DE"
},
{
"id": 9,
"name": "District of Columbia - DC"
},
{
"id": 10,
"name": "Florida - FL"
},
{
"id": 11,
"name": "Georgia - GA"
},
{
"id": 12,
"name": "Hawaii - HI"
},
{
"id": 13,
"name": "Idaho - ID"
},
{
"id": 14,
"name": "Illinois - IL"
},
{
"id": 15,
"name": "Indiana - IN"
},
{
"id": 16,
"name": "Iowa - IA"
},
{
"id": 17,
"name": "Kansas - KS"
},
{
"id": 18,
"name": "Kentucky - KY"
},
{
"id": 19,
"name": "Louisiana - LA"
},
{
"id": 20,
"name": "Maine - ME"
},
{
"id": 33,
"name": "Maryland - MD"
},
{
"id": 34,
"name": "Massachusetts - MA"
},
{
"id": 35,
"name": "Michigan - MI"
},
{
"id": 36,
"name": "Minnesota - MN"
},
{
"id": 37,
"name": "Mississippi - MS"
},
{
"id": 38,
"name": "Missouri - MO"
},
{
"id": 21,
"name": "Montana - MT"
},
{
"id": 22,
"name": "Nebraska - NE"
},
{
"id": 23,
"name": "Nevada - NV"
},
{
"id": 24,
"name": "New Hampshire - NH"
},
{
"id": 25,
"name": "New Jersey - NJ"
},
{
"id": 26,
"name": "New Mexico - NM"
},
{
"id": 27,
"name": "New York - NY"
},
{
"id": 28,
"name": "North Carolina - NC"
},
{
"id": 29,
"name": "North Dakota - ND"
},
{
"id": 30,
"name": "Ohio - OH"
},
{
"id": 31,
"name": "Oklahoma - OK"
},
{
"id": 32,
"name": "Oregon - OR"
},
{
"id": 39,
"name": "Pennsylvania - PA"
},
{
"id": 40,
"name": "Rhode Island - RI"
},
{
"id": 41,
"name": "South Carolina - SC"
},
{
"id": 42,
"name": "South Dakota - SD"
},
{
"id": 43,
"name": "Tennessee - TN"
},
{
"id": 44,
"name": "Texas - TX"
},
{
"id": 45,
"name": "Utah - UT"
},
{
"id": 46,
"name": "Vermont - VT"
},
{
"id": 47,
"name": "Virginia - VA"
},
{
"id": 48,
"name": "Washington - WA"
},
{
"id": 49,
"name": "West Virginia - WV"
},
{
"id": 50,
"name": "Wisconsin - WI"
},
{
"id": 51,
"name": "Wyoming - WY"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get organization branding info
requires authentication
Returns the authenticated organization's public profile and settings: business name, address, phone, website, branding color, logo, status, subscription package and client portal/onboarding display flags. Read-only.
Use this when the user asks for the company's name, contact details, address, branding/colors or logo, or to check whether the organization can use onboarding (organization_can_have_onboarding).
Do not use this to check premium (WordPress plugin) access — use Check whether an organization is premium (GET /api/v2/check_premium_organization) instead.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/organization_data" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/organization_data"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/organization_data';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/organization_data'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"organization": {
"analytic_enabled": 1,
"branding_color": "#39A597",
"business_address": "1502 Morse St",
"business_city": "Houston",
"business_lat": "29.7521804",
"business_lng": "-95.4058215",
"business_name": "Magnificent Scoopers 777",
"business_phone": "2025550101",
"business_state": "Texas",
"business_website": "https://www.sweepandgo.com/",
"business_zip": "77019",
"can_call_company_phone_client_portal": "1",
"can_text_company_phone_client_portal": "1",
"card_connect_site": null,
"charges_enabled": 1,
"commercial_inventory_tracking": "0",
"ga_tracking_id": "null",
"logo": "",
"organization": "magnificent-scoopers-777-p4ycx",
"organization_can_have_onboarding": true,
"organization_id": 161,
"organization_name": "Magnificent Scoopers 777",
"organization_status": "active",
"pay_period": "monthly",
"payroll_filter": "years_in_service,revenue,revenue_adjustment,distance,overtime_hours,vacation_hours,tips,reimbursement,deduction,number_of_jobs,number_of_complaints,mileage_rate,base_percentage,fixed_rate",
"rating_tipping": "enabled_all",
"send_invoice_email": "1",
"show_company_address_client_portal": "1",
"show_company_email_client_portal": "1",
"show_company_phone_client_portal": "1",
"show_logo_onboarding": "1",
"show_name_onboarding": "0",
"show_on_list": "0",
"show_payroll_filed_tech": "1",
"show_rating_comment_fieldtech": "1",
"subscription_package": "Professional",
"website": "http://www.superskooopers.com"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get default onboarding coupon if exists
requires authentication
Returns the coupon that the organization has set as the default for new client onboarding (code, name, percent or amount off, duration), if one exists. Read-only.
Use this when the user asks "is there a current promo / discount for new clients?" or to pre-fill the coupon field on a signup form. Do not use this to validate a coupon code entered by the client — use Check coupon code valid (GET /api/v2/client_on_boarding/coupon_find) instead.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find_default" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find_default"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find_default';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find_default'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"coupon": {
"coupon_id": "50POFF",
"coupon_name": "Spring Season",
"percent_off": "20",
"amount_off": null,
"duration_in_months": 0,
"duration": "once"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check coupon code valid
requires authentication
Validates a specific coupon code for the organization and, if valid, returns its discount details (percent or amount off, duration, number of months). Read-only; the coupon is not redeemed.
Use this when a prospect provides a coupon code and you need to confirm it is valid before onboarding. Do not use this to find the default promo — use Get default onboarding coupon if exists — or to create a new coupon — use Create coupon for residential subscriptions (POST /api/v2/coupon).
If the account runs any special promos, new clients may enter a coupon code. To create promos and coupon codes, go to Employee Portal > Billing > Coupons > New.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find?coupon_id=5pr1nG" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find"
);
const params = {
"coupon_id": "5pr1nG",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'coupon_id' => '5pr1nG',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/coupon_find'
params = {
'coupon_id': '5pr1nG',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"coupon": {
"percent_off": "25.00",
"amount_off": null,
"duration_in_months": 3,
"duration": "repeating",
"coupon_id": "5pr1nG",
"coupon_name": "Spring Sale NEW"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check client email exists
requires authentication
Checks whether a client with the given email already exists as an active client within the organization. Returns exists true/false. Read-only.
Use this before onboarding a new client to avoid duplicates — the onboarding endpoint rejects emails that already belong to an active client (HTTP 409). Do not use this to retrieve client details — use Search client by email (POST /api/v2/clients/client_search) instead.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_client_email_exists?email=john%40doe.com" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_client_email_exists"
);
const params = {
"email": "john@doe.com",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_client_email_exists';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'email' => 'john@doe.com',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_client_email_exists'
params = {
'email': 'john@doe.com',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"exists": true
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get thank you messages to show up on complete onboarding client
requires authentication
Returns the organization's configured thank you page contents (HTML) per signup type: credit card signup, check payment signup and one-time cleanup. Read-only.
Use this after a client has been successfully onboarded to show the matching confirmation message, or when the user asks what message clients see after signing up.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/thank_you_pages" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/thank_you_pages"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/thank_you_pages';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/thank_you_pages'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"thank_you_pages": [
{
"type": "credit_card_sign_up",
"content": "<p>Thank You For Signing Up</p><br><p>We have just sent you an email confirmation and login information to our client portal. We will also contact you to confirm your information and schedule a start date!</p><br>Payment Details:<ul><li>You have enrolled in our subscription payment option.</li><li>By far, the easiest way to pay for services</li><li>Your card will be charged after the completion the initial cleanup.</li><li>We will send you invoices according to your billing option and billing cycle and your card will be auto-debited according to NET terms on your account.</li></ul><br><p>If at any time, you have questions about your service or would like to change your card information or cancel monthly service, please contact us via client portal, email or phone.</p><br><p>Thank you.</p>"
},
{
"type": "check_payment_sign_up",
"content": "<p>Thank You for Signing Up</p><br><p>We have just sent you an email confirmation and login information to our client portal. We will also contact you to confirm your information and schedule a start date!</p><br>Payment Details:<ul><li>You have chosen to pay by check for your services.</li><li>Payment is required for the initial cleanup on completion. Your technician can collect a check at time of cleanup. If you will not be home, please leave a check for the larger amount of the Estimated Initial Cleanup (please see your confirmation email for estimate).</li><li>For regular services, we will email your recurring invoices according to your billing option and cycle, payment is due according to NET terms on your account.</li><li>If you would like to switch to auto pay, please just enter you credit card details within your client portal. </li></ul><br><p>If at any time, you have questions about your service, please contact us via email or phone.</p><br><p>Thank you.</p>"
},
{
"type": "one_time_clean_up",
"content": "<p>Thank you for Requesting a One Time Cleanup</p><br><p>We have just sent you an email confirmation and login information to our client portal. We will also contact you to confirm your information and schedule your cleanup.</p><br><p>Thank you.</p>"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get out of area form fields
requires authentication
Returns the field configuration of the short "out of service area" form shown to prospects whose ZIP code is not within the service area. Read-only. If the zip code is not within your service area, your prospect will be asked to fill out a short form so you could research more. After the form is submitted with Save out of service area lead (POST /api/v2/client_on_boarding/out_of_service_form), the account will receive an email with lead information.
Use this after Check zip code exists in your account returned not_exists.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"form_fields": [
{
"id": 4658,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "zip_code",
"step": 3,
"frontend_name": "Zip code",
"backend_name": "Zip code",
"one_time": true,
"recurring": true,
"show": true,
"required": true,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 27,
"frontend_sort": 27,
"locked_options": false,
"hint": ""
},
{
"id": 4659,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "name",
"step": 3,
"frontend_name": "Name",
"backend_name": "Name",
"one_time": true,
"recurring": true,
"show": true,
"required": true,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 28,
"frontend_sort": 28,
"locked_options": false,
"hint": ""
},
{
"id": 4660,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "email_address",
"step": 3,
"frontend_name": "Email address",
"backend_name": "Email address",
"one_time": true,
"recurring": true,
"show": true,
"required": true,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 29,
"frontend_sort": 29,
"locked_options": false,
"hint": ""
},
{
"id": 4662,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "phone",
"step": 3,
"frontend_name": "Phone number",
"backend_name": "Phone number",
"one_time": true,
"recurring": true,
"show": true,
"required": false,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 30,
"frontend_sort": 30,
"locked_options": false,
"hint": ""
},
{
"id": 4661,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "address",
"step": 3,
"frontend_name": "Address",
"backend_name": "Address",
"one_time": true,
"recurring": true,
"show": true,
"required": true,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 31,
"frontend_sort": 31,
"locked_options": false,
"hint": ""
},
{
"id": 4663,
"organization_form_id": 290,
"frontend_type": "textfield",
"frontend_description": "",
"backend_description": "",
"slug": "comment",
"step": 3,
"frontend_name": "Comment",
"backend_name": "Comment",
"one_time": true,
"recurring": true,
"show": true,
"required": false,
"optional_show": true,
"optional_required": false,
"backend_type": "textfield",
"value": "",
"options": "",
"locked": false,
"backend_sort": 32,
"frontend_sort": 32,
"locked_options": false,
"hint": ""
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Save out of service area lead
requires authentication
Saves a prospect whose ZIP code is outside the service area as an out of area lead and sends the organization an email with the lead information. This is a write operation. Repeated submissions with the same email within 10 minutes are ignored.
Use this when the prospect's ZIP code is not serviced (Check zip code exists in your account returned not_exists) and they want to be contacted if service becomes available.
Do not use this for in-area prospects — onboard them with Onboard a new residential client in Sweep&Go (PUT /api/v1/residential/onboarding). To read saved out of area leads, use Get out of area leads (GET /api/v1/leads/out_of_service).
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"name\": \"Ena Doe\",
\"address\": \"1502 Morse St\",
\"email_address\": \"ena@doe.com\",
\"zip_code\": \"12345\",
\"comment\": \"Demo comment\",
\"phone\": \"2025550101\",
\"marketing_allowed\": 1,
\"marketing_allowed_source\": \"open_api\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Ena Doe",
"address": "1502 Morse St",
"email_address": "ena@doe.com",
"zip_code": "12345",
"comment": "Demo comment",
"phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'name' => 'Ena Doe',
'address' => '1502 Morse St',
'email_address' => 'ena@doe.com',
'zip_code' => '12345',
'comment' => 'Demo comment',
'phone' => '2025550101',
'marketing_allowed' => 1,
'marketing_allowed_source' => 'open_api',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/out_of_service_form'
payload = {
"name": "Ena Doe",
"address": "1502 Morse St",
"email_address": "ena@doe.com",
"zip_code": "12345",
"comment": "Demo comment",
"phone": "2025550101",
"marketing_allowed": 1,
"marketing_allowed_source": "open_api"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check zip code exists in your account
requires authentication
Checks whether a ZIP code is inside the authenticated organization's service area. Returns exists or not_exists. Read-only.
Use this when the user asks "do you service ZIP 12345?" and as the first step of onboarding, before requesting a price or the signup form.
If the result is not_exists, use Get out of area form fields and Save out of service area lead to capture the prospect instead.
Do not use this to choose between several organizations — use Find the nearest eligible organization for a ZIP code (GET /api/v2/check_zip_code_multi_organizations) instead.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_zip_code_exists" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"value\": \"12345\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_zip_code_exists"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"value": "12345"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_zip_code_exists';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'value' => '12345',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/client_on_boarding/check_zip_code_exists'
payload = {
"value": "12345"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"exists": "not_exists"
}
Example response (200):
{
"exists": "exists"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
One time invoice charge using credit cards
Endpoints for paying an existing invoice with a credit card in a single charge.
Typical flow: first call "Check invoice status" to get the remaining balance and the payment gateway
configured for the account, then call the matching charge endpoint — "One time payment using Stripe" when
the gateway is stripe, or "One time payment using CardPointe" when the gateway is fts (CardPointe /
CardConnect). The charge endpoints require a card token produced by the gateway's client-side tokenization;
raw card numbers are never accepted. To record a check payment instead, use "One time check payment"
(PUT /api/v1/invoice/one_time).
Check invoice status
requires authentication
Returns the remaining (unpaid) balance of an invoice and the payment gateway configured for the account
(fts = CardPointe / CardConnect, stripe = Stripe, none = no card gateway).
Always call this before charging an invoice, to confirm there is a balance to pay and to choose the correct charge endpoint. Use it also when the user asks "how much is still owed on invoice X". To browse or find invoices use "Get invoices" (GET /api/v2/invoices). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/one_time_payment/check_invoice?invoice_number=3-3-190207-2-4" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/one_time_payment/check_invoice"
);
const params = {
"invoice_number": "3-3-190207-2-4",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/one_time_payment/check_invoice';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'invoice_number' => '3-3-190207-2-4',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/one_time_payment/check_invoice'
params = {
'invoice_number': '3-3-190207-2-4',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"invoice_remaining": "12.23",
"payment_gateway": "fts/stripe/none"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
One time payment using Stripe
requires authentication
Charges the invoice using Stripe and marks it as paid when successful.
Use this only when "Check invoice status" (GET /api/v2/one_time_payment/check_invoice) returned
payment_gateway = stripe. For CardPointe accounts use "One time payment using CardPointe"
(PUT /api/v2/one_time_payment/cc_payment); for check payments use "One time check payment"
(PUT /api/v1/invoice/one_time).
This is a write operation: it charges the client's card for real money. Confirm the invoice and amount with the user before calling.
Example request:
curl --request PUT \
"https://openapi.sweepandgo.com/api/v2/one_time_payment/stripe_payment" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"invoice_number\": \"3-3-190207-2-4\",
\"amount\": \"67.98\",
\"name_on_card\": \"John Doe\",
\"token\": \"tok_1E0rfhHLLICwofnx4bUzDZis\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/one_time_payment/stripe_payment"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"invoice_number": "3-3-190207-2-4",
"amount": "67.98",
"name_on_card": "John Doe",
"token": "tok_1E0rfhHLLICwofnx4bUzDZis"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/one_time_payment/stripe_payment';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'invoice_number' => '3-3-190207-2-4',
'amount' => '67.98',
'name_on_card' => 'John Doe',
'token' => 'tok_1E0rfhHLLICwofnx4bUzDZis',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/one_time_payment/stripe_payment'
payload = {
"invoice_number": "3-3-190207-2-4",
"amount": "67.98",
"name_on_card": "John Doe",
"token": "tok_1E0rfhHLLICwofnx4bUzDZis"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"status": "paid"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
One time check payments
Endpoints for recording payments made by check (paid outside of a card gateway) against residential client invoices. These endpoints do not charge a card. To charge an invoice by credit card use the "One time payment using Stripe" or "One time payment using CardPointe" endpoints instead.
One time check payment
requires authentication
Records a check payment (successful or failed) against an existing residential client invoice, identified by its invoice number. No money is charged — this only registers a payment that was already received outside the system.
This is a write operation: it creates a payment record and, when status is successful, affects the invoice balance.
Use this when the user says a client paid an invoice by check and wants it recorded.
The invoice number can be obtained from "Get invoices" (GET /api/v2/invoices); use "Check invoice status"
(GET /api/v2/one_time_payment/check_invoice) to see the remaining balance first.
To charge a credit card use "One time payment using Stripe" (PUT /api/v2/one_time_payment/stripe_payment)
or "One time payment using CardPointe" (PUT /api/v2/one_time_payment/cc_payment).
Example request:
curl --request PUT \
"https://openapi.sweepandgo.com/api/v1/invoice/one_time" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"invoice_number\": \"3-3-190207-2-4\",
\"reference_number\": \"ref_8798yhjasa\",
\"amount\": \"67.98\",
\"status\": \"successful\",
\"billing_address\": \"635 Go Man Go Dr\",
\"billing_city\": \"Stafford\",
\"billing_state\": \"Texas\",
\"billing_zip\": \"77477\",
\"name\": \"John Doe\",
\"email\": \"mail@mail.com\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v1/invoice/one_time"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"invoice_number": "3-3-190207-2-4",
"reference_number": "ref_8798yhjasa",
"amount": "67.98",
"status": "successful",
"billing_address": "635 Go Man Go Dr",
"billing_city": "Stafford",
"billing_state": "Texas",
"billing_zip": "77477",
"name": "John Doe",
"email": "mail@mail.com"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/invoice/one_time';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'invoice_number' => '3-3-190207-2-4',
'reference_number' => 'ref_8798yhjasa',
'amount' => '67.98',
'status' => 'successful',
'billing_address' => '635 Go Man Go Dr',
'billing_city' => 'Stafford',
'billing_state' => 'Texas',
'billing_zip' => '77477',
'name' => 'John Doe',
'email' => 'mail@mail.com',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/invoice/one_time'
payload = {
"invoice_number": "3-3-190207-2-4",
"reference_number": "ref_8798yhjasa",
"amount": "67.98",
"status": "successful",
"billing_address": "635 Go Man Go Dr",
"billing_city": "Stafford",
"billing_state": "Texas",
"billing_zip": "77477",
"name": "John Doe",
"email": "mail@mail.com"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Reports
Endpoints for retrieving organization-level statistics and operational reports.
The "Count ..." endpoints return a single all-time number (no date filters) and are meant for quick summary questions such as "how many active clients do we have". For per-day or per-employee detail use the "Route planning report" (planned work for a date) or the "Completed jobs report" (work done on a date or date range). "List of active staff" returns the employees (field techs) of the organization. All endpoints in this group are read-only.
Count dogs for happy clients
requires authentication
Returns a single number: the total number of dogs belonging to the organization's happy clients.
Use this when the user asks "how many dogs do we service" or "how many happy dogs do we have". To get the number of clients instead of dogs, use "Count happy clients" (GET /api/v2/report/count_happy_clients). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/count_happy_dogs" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/count_happy_dogs"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/count_happy_dogs';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/count_happy_dogs'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": 23
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Count happy clients
requires authentication
Returns a single number: the total number of the organization's happy clients.
Use this when the user asks for the happy clients count as a summary figure. For the number of currently active clients use "Count active clients" (GET /api/v2/report/count_active_clients); for the actual client records use "Get active clients" (GET /api/v1/clients/active). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/count_happy_clients" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/count_happy_clients"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/count_happy_clients';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/count_happy_clients'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": 23
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Count active clients
requires authentication
Returns a single number: the total number of active clients in the organization.
Use this when the user asks "how many active clients do we have". Do not use this to list clients — use "Get active clients" (GET /api/v1/clients/active) to get the client records instead. Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/count_active_clients" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/count_active_clients"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/count_active_clients';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/count_active_clients'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": 23
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Count completed jobs
requires authentication
Returns a single number: the all-time total of completed jobs (cleanups) for the organization.
Use this when the user asks "how many jobs/cleanups have we completed" as a summary figure. This endpoint has no date filter — for completed jobs on a specific date or date range (with job details) use "Completed jobs report" (GET /api/v2/report/completed_jobs_report). Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/jobs_count" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/jobs_count"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/jobs_count';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/jobs_count'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": 23
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List of active staff
requires authentication
Returns the active staff members (employees / field techs) of the organization with their ID, name, email, phone and calendar color.
Use this when the user asks "who works for us" or "list our technicians", or when you need an employee
name or ID to match against other data (e.g. the assigned_to field on clients or the employees in the
route planning report). Inactive employees are not included.
Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/staff_select_list" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/staff_select_list"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/staff_select_list';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/staff_select_list'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"data": [
{
"id": 1,
"name": "John Doe",
"email": "john@doe.com",
"color": "#87332",
"phone": "2025550101",
"status": "active"
},
{
"id": 2,
"name": "Jane Doe",
"email": "jane@doe.com",
"color": "#3355AA",
"phone": "2025550102",
"status": "active"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Route planning report
requires authentication
Returns a route-planning report for each employee with assigned jobs on the requested date: number of jobs, driving time, cleanup time, total duration, distance and estimated revenue per route.
Use this when the user asks about the planned workload for a day, e.g. "how long are the routes tomorrow", "which tech has the most jobs on Monday" or "estimated revenue for today's routes". Works for past, current and future dates. For the individual jobs on the Dispatch Board use "Get Dispatch Board jobs for a date" (GET /api/v1/dispatch_board/jobs_for_date); for jobs that were actually completed use "Completed jobs report" (GET /api/v2/report/completed_jobs_report). Read-only.
All time values are returned in minutes, and distance is returned in kilometers.
The total route duration is calculated as:
duration = driving_time + cleanup_time
The price field represents the estimated revenue for all jobs included
in the employee's route. It does not necessarily represent finalized or
collected revenue.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/route_planning_report?date=2026-09-21" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/route_planning_report"
);
const params = {
"date": "2026-09-21",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/route_planning_report';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'date' => '2026-09-21',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/route_planning_report'
params = {
'date': '2026-09-21',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"route_reports": [
{
"assigned_to_name": "John Doe",
"date": "2026-09-21",
"duration": 240,
"driving_time": 60,
"cleanup_time": 180,
"distance": 68.4,
"number_of_jobs": 18,
"price": 540
},
{
"assigned_to_name": "Emma Doe",
"date": "2026-09-21",
"duration": 180,
"driving_time": 45,
"cleanup_time": 135,
"distance": 51.2,
"number_of_jobs": 12,
"price": 375.5
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Completed jobs report
requires authentication
Returns a detailed, job-level report of completed jobs (cleanups) for a specific date or date range.
Use this when the user asks "which jobs were completed yesterday / last week", "who cleaned client X's yard on date Y", or wants job-level detail for past work. Only today and past dates are allowed — for planned future work use "Route planning report" (GET /api/v2/report/route_planning_report) or "Get Dispatch Board jobs for a date" (GET /api/v1/dispatch_board/jobs_for_date). For just an all-time total use "Count completed jobs" (GET /api/v2/report/jobs_count). Read-only.
Provide either date for a single-day report or both date_from and date_to for a date-range report.
All dates must be today or in the past.
Possible job status values:
- pending (1)
- completed (2)
- skipped (3)
- missed (4)
- started (5)
- dispatched (6)
Possible job types:
- custom
- initial
- one_time
- reclean
- recurring
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/report/completed_jobs_report?date=2026-07-13&date_from=2026-01-01&date_to=2026-01-31" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/report/completed_jobs_report"
);
const params = {
"date": "2026-07-13",
"date_from": "2026-01-01",
"date_to": "2026-01-31",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/report/completed_jobs_report';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'date' => '2026-07-13',
'date_from' => '2026-01-01',
'date_to' => '2026-01-31',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/report/completed_jobs_report'
params = {
'date': '2026-07-13',
'date_from': '2026-01-01',
'date_to': '2026-01-31',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"job_list": [
{
"commercial_name": null,
"type": "custom",
"quantity": 1,
"first_name": "Pete",
"last_name": "Peterson",
"address": "149 W 300 N",
"city": "Logan",
"zip": "84321",
"state_name": "Utah",
"assigned_to_name": "John Doe",
"assigned_to_id": 509,
"status_id": 2,
"start_time": "2026-07-13 04:30:59",
"end_time": "2026-07-13 04:40:25",
"pricing_plan_name": "Regular Plan",
"service_plan_name": "1d-1xW",
"service_plan_slug": "once_a_week",
"date": "2026-07-13",
"note": null,
"skip_reason_title": null,
"count_cross_sells": 0,
"price": "25.00",
"additional_services": null,
"status_name": "completed",
"duration": "9:26",
"service_label": null
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Gift card certificates
Endpoints for managing gift card certificates that a purchaser buys for a recipient (e.g. sold on the company website).
Send new Gift card certificate
requires authentication
Records a purchased gift card certificate (purchaser, recipient, amount, purchase and expiration dates, unique reference number) in the organization's account. This is a write operation.
Use this when a gift certificate has been sold (e.g. through an external website checkout) and must be registered in Sweep&Go, or when the user asks to create/issue a gift card. Do not use this to create discount codes — use Create coupon for residential subscriptions (POST /api/v2/coupon) instead.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/gift_card" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"purchaser_name\": \"John Doe\",
\"purchaser_email\": \"jon@doe.com\",
\"purchaser_phone\": \"2025550101\",
\"amount\": \"12.45\",
\"expires\": \"2024-12-23\",
\"bought\": \"2024-11-23\",
\"reference_number\": \"12c45-wa3B\",
\"recipient_name\": \"Jane Doe\",
\"recipient_email\": \"jane@doe.com\",
\"special_note\": \"For your birthday\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/gift_card"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"purchaser_name": "John Doe",
"purchaser_email": "jon@doe.com",
"purchaser_phone": "2025550101",
"amount": "12.45",
"expires": "2024-12-23",
"bought": "2024-11-23",
"reference_number": "12c45-wa3B",
"recipient_name": "Jane Doe",
"recipient_email": "jane@doe.com",
"special_note": "For your birthday"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/gift_card';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'purchaser_name' => 'John Doe',
'purchaser_email' => 'jon@doe.com',
'purchaser_phone' => '2025550101',
'amount' => '12.45',
'expires' => '2024-12-23',
'bought' => '2024-11-23',
'reference_number' => '12c45-wa3B',
'recipient_name' => 'Jane Doe',
'recipient_email' => 'jane@doe.com',
'special_note' => 'For your birthday',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/gift_card'
payload = {
"purchaser_name": "John Doe",
"purchaser_email": "jon@doe.com",
"purchaser_phone": "2025550101",
"amount": "12.45",
"expires": "2024-12-23",
"bought": "2024-11-23",
"reference_number": "12c45-wa3B",
"recipient_name": "Jane Doe",
"recipient_email": "jane@doe.com",
"special_note": "For your birthday"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Coupons
Endpoints for managing coupons (promo/discount codes) for residential subscriptions. Created coupons can be entered by new clients during onboarding. To validate an existing code use Check coupon code valid (GET /api/v2/client_on_boarding/coupon_find).
Create coupon for residential subscriptions
requires authentication
Creates a new coupon (percent or fixed amount discount) in the organization's account and returns its code and name. This is a write operation: the coupon becomes immediately available to clients.
Use this when the user asks to create a promo / discount code, e.g. "create a 20% off coupon SPRING for the first 3 months". Do not use this to check whether a coupon exists or is valid — use Check coupon code valid (GET /api/v2/client_on_boarding/coupon_find) instead.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/coupon" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"coupon_id\": \"5pr1nG\",
\"name\": \"Spring Season\",
\"coupon_type\": \"amount\",
\"duration\": \"repeating\",
\"percent_off\": \"20\",
\"amount_off\": \"22.51\",
\"redeem_by\": \"2024-12-23\",
\"max_redemptions\": 5,
\"number_of_months\": 2
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/coupon"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"coupon_id": "5pr1nG",
"name": "Spring Season",
"coupon_type": "amount",
"duration": "repeating",
"percent_off": "20",
"amount_off": "22.51",
"redeem_by": "2024-12-23",
"max_redemptions": 5,
"number_of_months": 2
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/coupon';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'coupon_id' => '5pr1nG',
'name' => 'Spring Season',
'coupon_type' => 'amount',
'duration' => 'repeating',
'percent_off' => '20',
'amount_off' => '22.51',
'redeem_by' => '2024-12-23',
'max_redemptions' => 5,
'number_of_months' => 2,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/coupon'
payload = {
"coupon_id": "5pr1nG",
"name": "Spring Season",
"coupon_type": "amount",
"duration": "repeating",
"percent_off": "20",
"amount_off": "22.51",
"redeem_by": "2024-12-23",
"max_redemptions": 5,
"number_of_months": 2
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success",
"coupon": {
"coupon_id": "5pr1nG",
"name": "Spring Season"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Free quotes
Endpoints for retrieving free quotes requested by prospects through the onboarding form (price requests that did not necessarily result in a signup).
Get free quotes
requires authentication
Returns the list of free quotes requested by prospects: contact details (name, email, cell phone, marketing consent), number of dogs, requested cleanup frequency, when the yard was last cleaned, issued coupon code and request date. Read-only.
Use this when the user asks who requested a quote, wants to follow up with prospects that asked for a price, or wants quote statistics. Do not use this for leads or out of service area leads — use Get leads (GET /api/v1/leads/list) or Get out of area leads (GET /api/v1/leads/out_of_service). To calculate a new price use Get price, tax percent, cross sells... (GET /api/v2/client_on_boarding/price_registration_form).
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/free_quotes" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/free_quotes"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/free_quotes';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/free_quotes'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"free_quotes": [
{
"coupon_code": "UKdJ5C0W",
"number_of_dogs": "4",
"clean_up_frequency": "five_times_a_week",
"last_time_yard_was_thoroughly_cleaned": "two_months",
"your_email_address": "client@example.com",
"cell_phone_number": "2025550101",
"marketing_allowed": 1,
"first_name": "Ena",
"last_name": "Doe",
"created_at": "2026-02-15 10:42:31"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Inbound SMS notifications
System callback endpoints used by the SMS provider (Twilio) for "on the way" notifications sent by field techs before a cleanup. One endpoint receives the client's SMS reply about whether the dogs are secured, the other receives message delivery status updates so the field tech can be notified. These endpoints are internal integrations, not intended for end users or AI assistants; they do not return any client, job or billing data.
Dog secured confirmation request
requires authentication
Receives an inbound SMS reply from a client to an "on the way" notification, telling the field tech
whether they can enter the yard (ENT) or must not enter (DNE), and forwards it for processing.
Internal endpoint called by Twilio — not intended for end users or AI assistants. Do not use it to send messages or to look up client data. This is a write operation: it records the client's reply and notifies the assigned field tech.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/text-inbound/on-the-way/check-dogs" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"From\": \"12025550102\",
\"To\": \"12025550101\",
\"SmsMessageSid\": \"89iwieweow8e49038408902\",
\"Body\": \"ENT\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/text-inbound/on-the-way/check-dogs"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"From": "12025550102",
"To": "12025550101",
"SmsMessageSid": "89iwieweow8e49038408902",
"Body": "ENT"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/text-inbound/on-the-way/check-dogs';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'From' => '12025550102',
'To' => '12025550101',
'SmsMessageSid' => '89iwieweow8e49038408902',
'Body' => 'ENT',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/text-inbound/on-the-way/check-dogs'
payload = {
"From": "12025550102",
"To": "12025550101",
"SmsMessageSid": "89iwieweow8e49038408902",
"Body": "ENT"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Twilio webhook
requires authentication
Receives the delivery status of an "on the way" (or similar) notification sent to a client and notifies the field tech that the client has received the notification.
Internal endpoint called by Twilio / the field tech portal — not intended for end users or AI assistants. This is a write operation: it stores the delivery status and triggers a notification to the field tech.
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/text-twilio/on-the-way/webhook" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"status\": \"delivered\",
\"job_id\": \"123\",
\"client\": \"cus_9is0ia893\",
\"chanel\": \"sms\",
\"type\": \"on_the_way\",
\"staff_id\": 1,
\"local_message_id\": \"270444-10-1753266841837\",
\"message_id\": \"SM4a13b79c2b6a0e17bb77b6c0ce0d4a34\",
\"error_code\": 1
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/text-twilio/on-the-way/webhook"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"status": "delivered",
"job_id": "123",
"client": "cus_9is0ia893",
"chanel": "sms",
"type": "on_the_way",
"staff_id": 1,
"local_message_id": "270444-10-1753266841837",
"message_id": "SM4a13b79c2b6a0e17bb77b6c0ce0d4a34",
"error_code": 1
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/text-twilio/on-the-way/webhook';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'status' => 'delivered',
'job_id' => '123',
'client' => 'cus_9is0ia893',
'chanel' => 'sms',
'type' => 'on_the_way',
'staff_id' => 1,
'local_message_id' => '270444-10-1753266841837',
'message_id' => 'SM4a13b79c2b6a0e17bb77b6c0ce0d4a34',
'error_code' => 1,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/text-twilio/on-the-way/webhook'
payload = {
"status": "delivered",
"job_id": "123",
"client": "cus_9is0ia893",
"chanel": "sms",
"type": "on_the_way",
"staff_id": 1,
"local_message_id": "270444-10-1753266841837",
"message_id": "SM4a13b79c2b6a0e17bb77b6c0ce0d4a34",
"error_code": 1
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"success": "success"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Packaged cross-sells
Endpoints for retrieving packaged cross-sells (service packages/bundles) offered by the organization. Packages are used with Create client with package subscription (POST /api/v2/client_on_boarding/create_client_with_package).
Get packaged cross-sells
requires authentication
Returns the organization's packaged cross-sells (service packages/bundles) with price, unit, tax, display settings and number of clients, plus the cross-sell placement, billing interval and billing category. Read-only.
Use this when the user asks which packages/plans are offered and what they cost, or to get the cross_sell_id, category and billing_interval needed by Create client with package subscription (POST /api/v2/client_on_boarding/create_client_with_package).
Do not use this for per-dog/frequency pricing or for regular (non-package) additional services — use Get price, tax percent, cross sells... (GET /api/v2/client_on_boarding/price_registration_form) instead.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/packages_list" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/packages_list"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/packages_list';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/packages_list'
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers)
response.json()Example response (200):
{
"cross_sells": [
{
"id": 201,
"name": "Starter Package",
"description": "Essential tools to get started with our service.",
"unit": "bundle",
"unit_amount": "20.00",
"taxable": 1,
"service": 0,
"tax_percent": "5.000",
"package": 1,
"package_order": 1,
"featured": 1,
"featured_label": "Most Popular",
"descriptions": "Includes basic deodorizer, gloves, and poop bags.",
"button_color": "#4CAF50",
"background_color": "#E8F5E9",
"featured_color": "#FFC107",
"cleanup_frequency": "weekly",
"count_clients": 110
},
{
"id": 202,
"name": "Premium Package",
"description": "Full service kit with advanced cleaning solutions.",
"unit": "box",
"unit_amount": "40.00",
"taxable": 1,
"service": 0,
"tax_percent": "5.000",
"package": 1,
"package_order": 2,
"featured": 0,
"featured_label": null,
"descriptions": "Includes premium scented sprays, large bags, and protective wear.",
"button_color": "#2196F3",
"background_color": "#E3F2FD",
"featured_color": null,
"cleanup_frequency": "bi-weekly",
"count_clients": 65
}
],
"cross_sells_placement": "top",
"billing_interval": "monthly",
"category": "cleanup"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Webhooks
Endpoints for inspecting outgoing webhooks of the organization tied to the API token. Sweep&Go sends a webhook (an HTTP POST to the webhook URL configured on the access token) whenever one of the events below happens. Use "List all webhook event types" to see which event types exist, "List triggered webhooks" to see webhooks that were already sent (with their payloads), and "Retry a triggered webhook" to re-send one of them, e.g. after the receiving endpoint was down. Webhook event types:
- free:quote - Free quote
- lead:out_of_service_area - Lead - out of service area
- lead:in_service_area - Lead - in service area
- lead:delete - Lead - deleted
- client:changed_status - Client - changed status
- client:changed_info - Client - changed info
- client:changed_address - Client - changed address
- client:client_onboarding_recurring - Client - client onboarding recurring
- client:client_onboarding_onetime - Client - client onboarding onetime
- client:subscription_created - Client - subscription created
- client:subscription_canceled - Client - subscription canceled
- client:subscription_paused - Client - subscription paused
- client:subscription_unpaused - Client - subscription unpaused
- client:invoice_finalized - Client - invoice finalized
- client:client_payment_declined - Client payment was declined
- client:client_payment_accepted - Client payment was accepted
- notification:on_the_way_notification - Notification - on the way notification
- notification:off_schedule_notification - Notification - off schedule notification
- notification:completed_job_notification - Notification - completed job notification
- notification:skipped_job_notification - Notification - skipped job notification
- notification:client_not_assigned - Notification - client not assigned
- client:client_assigned - Client - client assigned
- client:subscription_cancel_requested - Client - subscription cancel requested
- client:notification_settings_changed - Client - notification settings changed
- client:additional_contact_changed - Client - additional contact changed
- client:reviews_automation - Client - reviews automation
- client:areas_to_clean_changed - Client - areas to clean changed
- staff:staff_clock_in - Staff - staff clock in
- staff:staff_forgot_to_clock_out - Staff - staff forgot to clock out
- staff:shift_break_started - Staff - shift break started
- staff:shift_break_info - Staff - shift break info
- job:started - Job - started with info
- job:completed - Job - completed with info start time, end time, job type and price
- organization:client_onboarding_form_changed - Business - client onboarding form changed
- organization:cross_sells_changed - Business - cross sells changed
- payroll:shift_info - Payroll - shift info, work time, start time, end time, mileages, duration, break duration
- payroll:tip_info - Payroll - tip linked to invoice with amount
- dog:birthday - Send webhook on dog birthday 7 days in advance
- client:credit_card_link_created - Private credit card link created for add new credit card
- commercial:client_created - Commercial - client created
- commercial:client_changed_info - Commercial - client changed info
- commercial:client_changed_status - Commercial - client changed status
- commercial:location_created - Commercial - location created
- commercial:location_changed - Commercial - location changed
- commercial:location_deleted - Commercial - location deleted
- commercial:contact_created - Commercial - contact created
- commercial:contact_changed - Commercial - contact changed
- commercial:contact_deleted - Commercial - contact deleted
- commercial:subscription_created - Commercial - subscription created
- commercial:subscription_paused - Commercial - subscription paused
- commercial:subscription_unpaused - Commercial - subscription unpaused
- commercial:subscription_canceled - Commercial - subscription canceled
- commercial:invoice_finalized - Commercial - invoice finalized
- commercial:client_payment_declined - Commercial - client payment declined
- commercial:client_payment_accepted - Commercial - client payment accepted
- commercial:client_assigned - Commercial - client assigned
- commercial:client_no_assigned - Commercial - client no assigned
- commercial_notification:on_the_way_notification - Commercial Notification - on the way notification
- commercial_notification:off_schedule_notification - Commercial Notification - off schedule notification
- commercial_notification:completed_job_notification - Commercial Notification - completed job notification
- commercial_notification:skipped_job_notification - Commercial Notification - skipped job notification
- commercial_job:started - Commercial Job - started with info
List all webhook event types
Returns the catalogue of all webhook event types Sweep&Go can send (e.g. client:changed_status, job:completed), independent of the organization. Read-only.
Use this when the user asks which events/webhooks are available or what a webhook type means. To see webhooks that were actually sent to the organization use "List triggered webhooks" (GET /api/v1/webhooks/list).
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/webhooks/index"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/webhooks/index"
);
fetch(url, {
method: "GET",
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/webhooks/index';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/webhooks/index'
response = requests.request('GET', url, )
response.json()Example response (403):
Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
{
"errors": [
"Authorization failed"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List triggered webhooks
requires authentication
Returns a paginated list of webhooks that were already triggered (sent) for the organization, each with its id,
event type, destination webhook URL, payload (data) and creation time. Read-only.
Use this when the user wants to audit or debug webhook deliveries, inspect a webhook payload, or find the id
of a webhook to re-send with "Retry a triggered webhook" (PUT /api/v1/webhooks/retry).
For the list of available event types use "List all webhook event types" (GET /api/v1/webhooks/index).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v1/webhooks/list?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v1/webhooks/list"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/webhooks/list';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/webhooks/list'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (403):
Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
{
"errors": [
"API key is not valid"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Retry a triggered webhook
requires authentication
Re-sends a previously triggered webhook with its original event type and payload to the organization's webhook URL.
This is a write operation: it performs a new outgoing HTTP delivery of the webhook. Use this when the user wants to re-deliver a webhook that their system missed or failed to process. The webhook id is obtained from "List triggered webhooks" (GET /api/v1/webhooks/list).
Example request:
curl --request PUT \
"https://openapi.sweepandgo.com/api/v1/webhooks/retry" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"id\": \"e0e03073-a1a3-4f6e-82ff-81dab3772534\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v1/webhooks/retry"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"id": "e0e03073-a1a3-4f6e-82ff-81dab3772534"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v1/webhooks/retry';
$response = $client->put(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'id' => 'e0e03073-a1a3-4f6e-82ff-81dab3772534',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v1/webhooks/retry'
payload = {
"id": "e0e03073-a1a3-4f6e-82ff-81dab3772534"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('PUT', url, headers=headers, json=payload)
response.json()Example response (403):
Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
{
"errors": [
"API key is not valid"
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Billing Info
Endpoints for retrieving billing info - recurring and one-time invoices, payments and subscriptions.
Invoices are the amounts billed to clients (with status, total and remaining balance); payments are the
money actually received (charges, refunds, tips); subscriptions are the recurring service/billing plans
that generate invoices. Residential and commercial subscriptions are exposed by separate endpoints.
All endpoints are read-only, paginated and return organization-wide data (no per-client filter) — page
through results with page and length. To pay an invoice use the "One time payment" endpoints instead.
Get invoices
requires authentication
Returns a paginated list of invoices (residential and commercial) with invoice number, client, status, total, remaining balance, paid/refunded amounts and billing period.
Use this when the user asks about billed amounts, e.g. "show recent invoices", "which invoices are unpaid / still have a remaining balance", or "list one-time invoices". Do not use this for money actually collected — use "Get payments" (GET /api/v2/payments) instead. To check a single invoice's balance before charging it, use "Check invoice status" (GET /api/v2/one_time_payment/check_invoice). Read-only.
Use recurring type to return subscription invoices, or one_time to return all one-time invoices.
Draft and voided invoices are excluded.
Possible returned invoice types are: initial, one_time, prorated, subscription and variable.
Possible billing intervals are: annually, semi-annually, every_four_months, quarterly, every_two_months, monthly, 4_weeks, bi-weekly, weekly, daily, initial, one_time and prorated.
Possible categories are: postpaid, prepaid, cleanup and variable.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/invoices?page=1&length=20&type=recurring" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/invoices"
);
const params = {
"page": "1",
"length": "20",
"type": "recurring",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/invoices';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '1',
'length' => '20',
'type' => 'recurring',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/invoices'
params = {
'page': '1',
'length': '20',
'type': 'recurring',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"invoices": {
"current_page": 1,
"data": [
{
"created_at": "2026-07-02 00:03:23",
"tip_amount": "0.00",
"next_try_charging": null,
"commercial_client": "Test Business",
"commercial_location": "Location 1",
"invoice_number": "323-270-260702-8-62215",
"client_name": "Test Business",
"pay_method": "check",
"status": "paid",
"total": "12.00",
"type": "subscription",
"remaining": "0.00",
"category": "postpaid",
"billing_interval": "weekly",
"refunded": "0.00",
"paid": "12.00",
"period_end": "2026-07-09 00:03:23",
"period_start": "2026-07-02 00:03:23"
},
{
"created_at": "2026-07-14 05:03:02",
"tip_amount": "0.00",
"next_try_charging": null,
"commercial_client": null,
"commercial_location": null,
"invoice_number": "127-1104-200521-2-5830",
"client_name": "Frankie Hooper",
"pay_method": "credit_card",
"status": "paid",
"total": "52.67",
"type": "subscription",
"remaining": "0.00",
"category": "prepaid",
"billing_interval": "daily",
"refunded": "0.00",
"paid": "52.67",
"period_end": "2026-07-15 05:03:02",
"period_start": "2026-07-14 05:03:02"
}
],
"per_page": 10,
"from": 1,
"to": 10,
"total": 31,
"last_page": 4,
"next_page_url": "https://api.example.com/api/invoices/recurring?page=2",
"prev_page_url": null
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get payments
requires authentication
Returns a paginated list of payments received by the organization (date, amount, refunded amount, status, type, description, client and tip), for both residential and commercial clients.
Use this when the user asks about money collected, e.g. "show recent payments", "what did we receive this week", "list refunds". Do not use this for billed or outstanding amounts — use "Get invoices" (GET /api/v2/invoices) instead. Read-only.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/payments?page=1&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/payments"
);
const params = {
"page": "1",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/payments';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '1',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/payments'
params = {
'page': '1',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"payments": {
"current_page": 1,
"data": [
{
"date": "2026-07-06",
"amount": 22,
"amount_refunded": "0.00",
"status": "succeeded",
"type": "credit_card",
"description": "Payment for invoice 127-1060-200318-2-4420",
"client_name": "John Doe",
"tip_amount": "0.00",
"commercial_location": null,
"commercial_client": null
}
],
"per_page": 10,
"from": 1,
"to": 10,
"total": 300,
"last_page": 30,
"next_page_url": "https://api.example.com/api/payments?page=2",
"prev_page_url": null
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get residential subscriptions
requires authentication
Returns a paginated list of residential subscriptions with status, billing interval, price, service plan, number of dogs, client info, pause/termination details and applied coupon or tip.
Use this when the user asks about residential recurring service plans, e.g. "which subscriptions are paused", "why did clients cancel", "list active residential subscriptions". For commercial clients use "Get commercial subscriptions" (GET /api/v2/commercial/subscriptions) instead. Read-only.
Possible statuses: active, canceled, paused, pending.
Possible categories: cleanup, postpaid, prepaid.
Possible billing intervals: one_time, annually, semi-annually, every_four_months, quarterly, every_two_months, monthly, 4_weeks, bi-weekly, weekly, daily.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/subscriptions?page=1&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/subscriptions"
);
const params = {
"page": "1",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/subscriptions';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '1',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/subscriptions'
params = {
'page': '1',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"subscriptions": {
"current_page": 1,
"data": [
{
"status": "active",
"category": "cleanup",
"billing_interval": "monthly",
"start_date": "2026-08-05",
"end_date": null,
"current_period_end": "2026-08-23 04:02:25",
"canceled_at": null,
"client_name": "John Doe",
"client_email": "johndoe@email.com",
"client_address": "Test Street, Test City, Texas 88595",
"name": null,
"price": 20,
"pricing_plan": "Regular Plan",
"service_plan": "2d-1xW",
"frequency": "once_a_week",
"number_of_dogs": "2",
"zip_code": "88595",
"termination_reason": null,
"termination_comment": null,
"termination_note": null,
"pause_start_date": null,
"pause_end_date": null,
"pause_reason": null,
"coupon_code": null,
"coupon_total": null,
"coupon_percent": null,
"coupon_added": null,
"coupon_end": null,
"tip_amount": null,
"tip_added": null
}
],
"per_page": 10,
"from": 1,
"to": 10,
"total": 300,
"last_page": 30,
"next_page_url": "https://api.example.com/api/subscriptions?page=2",
"prev_page_url": null
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get commercial subscriptions
requires authentication
Returns a paginated list of commercial subscriptions with status, billing interval, price, service name, commercial client and location, and pause/termination details.
Use this when the user asks about recurring service for commercial clients (businesses, HOAs, apartment complexes and their locations). For residential clients use "Get residential subscriptions" (GET /api/v2/subscriptions) instead. Read-only.
Possible statuses: active, canceled, paused, pending.
Possible categories: cleanup, postpaid, prepaid.
Possible billing intervals: annually, semi-annually, quarterly, every_two_months, monthly, 4_weeks, bi-weekly, weekly, daily.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/commercial/subscriptions?page=1&length=20" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial/subscriptions"
);
const params = {
"page": "1",
"length": "20",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial/subscriptions';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '1',
'length' => '20',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial/subscriptions'
params = {
'page': '1',
'length': '20',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"subscriptions": {
"current_page": 1,
"data": [
{
"status": "active",
"category": "postpaid",
"billing_interval": "monthly",
"start_date": "2026-01-27",
"end_date": null,
"current_period_end": "2026-06-27 04:03:23",
"canceled_at": null,
"commercial_client": "Test Commercial",
"commercial_location": "Test Location",
"client_name": "Test Company",
"client_email": "testclient12345@email.com",
"client_address": "Test Street, Test City, Arizona 85001",
"service_name": "Test service",
"frequency": "2xW",
"price": 30,
"termination_reason": null,
"termination_comment": null,
"termination_note": null,
"pause_start_date": null,
"pause_end_date": null,
"pause_reason": null,
"tip_amount": null,
"tip_added": null
}
],
"per_page": 10,
"from": 1,
"to": 10,
"total": 300,
"last_page": 30,
"next_page_url": "https://api.example.com/api/commercial/subscriptions?page=2",
"prev_page_url": null
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Commercial clients list
Endpoints for listing, searching and inspecting commercial (business) clients within the organization tied to the API token. A commercial client (e.g. an HOA, apartment complex or business) has one or more locations, each with its own subscriptions and contacts. Commercial clients are identified by a client string (e.g. cc_MTPQPRUUUY7G), returned by the list and search endpoints and required by "Get commercial client details". For residential (homeowner) clients use the "Clients list" endpoints instead.
Get active commercial clients
requires authentication
Returns a paginated list of active commercial clients with their locations (without contacts). Read-only.
Use this when the user wants to browse or export all currently active commercial/business clients.
To find a specific commercial client use "Search commercial clients" (POST /api/v2/commercial_clients/search);
for location contacts use "Get commercial client details" (POST /api/v2/commercial_clients/client_details).
For residential clients use "Get active clients" (GET /api/v1/clients/active).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/commercial_clients/active?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial_clients/active"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/active';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/active'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "cc_MTPQPRUUUY7G",
"name": "Acme Corporation",
"status": "active",
"locations_count": 2,
"subscription_names": "2w-3d,Deodorising",
"locations": [
{
"location": "cl_ABCDEF123456",
"name": "Downtown Office",
"status": "active",
"email": "office@acme.com",
"billing_company_name": "Acme Corporation",
"billing_first_name": "John",
"billing_last_name": "Doe",
"billing_address": "3289 Summit Street",
"billing_city": "Davenport",
"billing_state": "Iowa",
"billing_zip": "52801",
"billing_country": "United States",
"subscription_names": "2w-3d",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "Once a week"
}
]
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 15,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get inactive commercial clients
requires authentication
Returns a paginated list of inactive (former or paused) commercial clients with their locations. Read-only.
Use this when the user asks about former or cancelled commercial/business clients.
For active ones use "Get active commercial clients" (GET /api/v2/commercial_clients/active);
for residential clients use "Get inactive clients" (GET /api/v1/clients/inactive).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/commercial_clients/inactive?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial_clients/inactive"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/inactive';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/inactive'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "cc_MTPQPRUUUY7G",
"name": "Acme Corporation",
"status": "inactive",
"locations_count": 1,
"subscription_names": "",
"locations": []
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 15,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get commercial clients with a subscription
requires authentication
Returns a paginated list of commercial clients that have at least one location with an active subscription.
Only the locations that have a subscription are returned for each client. The client status is not filtered,
so check the status field if you only need active clients. Read-only.
Use this when the user asks which commercial clients/locations are on a recurring plan or which subscriptions they have.
For the subscription records themselves (price, billing, status) use "Get commercial subscriptions" (GET /api/v2/commercial/subscriptions).
Iterate through pages using the page parameter and the paginate.total_pages value in the response.
Example request:
curl --request GET \
--get "https://openapi.sweepandgo.com/api/v2/commercial_clients/with_subscription?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}"const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial_clients/with_subscription"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/with_subscription';
$response = $client->get(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
],
'query' => [
'page' => '2',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/with_subscription'
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}
response = requests.request('GET', url, headers=headers, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "cc_MTPQPRUUUY7G",
"name": "Acme Corporation",
"status": "active",
"locations_count": 1,
"subscription_names": "2w-3d,Deodorising",
"locations": [
{
"location": "cl_ABCDEF123456",
"name": "Downtown Office",
"status": "active",
"subscription_names": "2w-3d,Deodorising",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "Once a week"
}
]
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 15,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Search commercial clients
requires authentication
Searches commercial clients by client name, location name or contact (first name, last name, company name, email or phone). Returns a paginated list of matching commercial clients with their locations and contacts. Matching is case-insensitive and partial (the term may appear anywhere in the field). Read-only.
Use this when the user refers to a commercial/business client, property or contact person by name, email or phone, and you need the commercial client identifier (e.g. cc_MTPQPRUUUY7G) or its locations. For residential clients use "Search clients by name" (GET /api/v1/clients/search_by_name) or "Search client by email" (POST /api/v2/clients/client_search).
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/commercial_clients/search?page=2" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"q\": \"Acme\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial_clients/search"
);
const params = {
"page": "2",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"q": "Acme"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/search';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'query' => [
'page' => '2',
],
'json' => [
'q' => 'Acme',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/search'
payload = {
"q": "Acme"
}
params = {
'page': '2',
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload, params=params)
response.json()Example response (200):
{
"data": [
{
"client": "cc_MTPQPRUUUY7G",
"name": "Acme Corporation",
"status": "active",
"locations_count": 1,
"subscription_names": "2w-3d",
"locations": [
{
"location": "cl_ABCDEF123456",
"name": "Downtown Office",
"status": "active",
"subscription_names": "2w-3d",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "Once a week",
"contacts": [
{
"company": false,
"first_name": "John",
"last_name": "Doe",
"role": "Owner",
"email": "john@acme.com",
"phone": "2025550101"
}
]
}
]
}
],
"paginate": {
"total": 1,
"count": 1,
"per_page": 15,
"current_page": 1,
"total_pages": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get commercial client details
requires authentication
Returns a single commercial client together with all of its locations and the contacts for each location. Returns 403 when the client is not found. Read-only.
Use this when the user asks for full details, locations or contact people of one specific commercial client. Requires the commercial client identifier (e.g. cc_MTPQPRUUUY7G) — obtain it first via "Search commercial clients" (POST /api/v2/commercial_clients/search) or the commercial client list endpoints. For residential clients use "Get client details and payments" (POST /api/v2/clients/client_details).
Example request:
curl --request POST \
"https://openapi.sweepandgo.com/api/v2/commercial_clients/client_details" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--data "{
\"client\": \"cc_MTPQPRUUUY7G\"
}"
const url = new URL(
"https://openapi.sweepandgo.com/api/v2/commercial_clients/client_details"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"client": "cc_MTPQPRUUUY7G"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/client_details';
$response = $client->post(
$url,
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
],
'json' => [
'client' => 'cc_MTPQPRUUUY7G',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));import requests
import json
url = 'https://openapi.sweepandgo.com/api/v2/commercial_clients/client_details'
payload = {
"client": "cc_MTPQPRUUUY7G"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()Example response (200):
{
"client": "cc_MTPQPRUUUY7G",
"name": "Acme Corporation",
"status": "active",
"locations_count": 1,
"subscription_names": "2w-3d",
"locations": [
{
"location": "cl_ABCDEF123456",
"name": "Downtown Office",
"status": "active",
"email": "office@acme.com",
"billing_company_name": "Acme Corporation",
"billing_first_name": "John",
"billing_last_name": "Doe",
"billing_address": "3289 Summit Street",
"billing_city": "Davenport",
"billing_state": "Iowa",
"billing_zip": "52801",
"billing_country": "United States",
"subscription_names": "2w-3d",
"service_days": "Monday",
"assigned_to": "Alissa Doe",
"cleanup_frequency": "Once a week",
"contacts": [
{
"company": false,
"first_name": "John",
"last_name": "Doe",
"company_name": null,
"role": "Owner",
"email": "john@acme.com",
"phone": "2025550101",
"address": "3289 Summit Street",
"city": "Davenport",
"state": "Iowa",
"zip": "52801",
"country": "United States",
"priority": "1",
"billing_contact": true,
"job_notifications": true,
"email_invoices": true,
"client_portal": false,
"field_tech_show": true,
"channel": "sms",
"on_the_way": true,
"completed": true,
"off_schedule": false,
"marketing_allowed": 1,
"marketing_allowed_updated_at": "2025-03-05 10:20:55",
"marketing_allowed_source": "open_api"
}
]
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.