MENU navbar-image

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"
        }
    }
]
 

Request      

GET api/token_generate/access_tokens

Query Parameters

organization_id   integer     

Organization ID. Example: 2

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
}
 

Request      

GET api/token_generate/access_token/{id}

URL Parameters

id   integer     

The ID of the access token. Example: 12

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
}
 

Request      

POST api/token_generate/access_token

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

organization_id   integer     

Organization ID the token belongs to. Example: 2

webhooks_url   string     

Webhook endpoint that will receive event payloads. Example: https://example.com/webhooks

enabled_events   string[]     

List of enabled webhook events.

0   string  optional    

Example: client:client_onboarding_recurring

1   string  optional    

Example: client:client_onboarding_onetime

description   string  optional    

Human-readable description of the token purpose. Example: Webhooks for client onboarding events

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"
}
 

Request      

GET api/token_generate/access_token/{id}/delete

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

URL Parameters

id   integer     

The ID of the access token to delete. Example: 12

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"
}
 

Request      

GET api/health

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"
    }
}
 

Request      

GET api/v1/welcome

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
    }
}
 

Request      

GET api/v2/welcome

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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
    }
}
 

Request      

GET api/v1/clients/active

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 15. Example: 20

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
    }
}
 

Request      

GET api/v1/clients/active_no_subscription

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 15. Example: 20

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
    }
}
 

Request      

GET api/v1/clients/inactive

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 15. Example: 20

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
    }
}
 

Request      

GET api/v1/clients/search_by_name

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

search   string     

Beginning of the client's first name, last name, or full name. Minimum 2 characters. Example: John Doe

page   integer  optional    

Get results for specific page. Example: 1

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 15. Example: 20

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"
        }
    ]
}
 

Request      

POST api/v2/clients/client_details

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

client   string     

Unique client identifier in your organization (the client field returned by the client list and search endpoints). Example: rcl_MTPQPRUUUY7G

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"
}
 

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"
}
 

Request      

PUT api/v1/residential/onboarding

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

zip_code   string     

Zip code. Must be a 5-digit number. Example: 12110

number_of_dogs   integer     

Number of dogs. Example: 2

last_time_yard_was_thoroughly_cleaned   string     

When the yard was last thoroughly cleaned. Available options are: one_week, two_weeks, three_weeks, one_month, two_months, 3-4_months, 5-6_months, 7-9_months, 10+_months. Example: one_week

clean_up_frequency   string     

Cleanup frequency. Available options are: seven_times_a_week, six_times_a_week, five_times_a_week, four_times_a_week, three_times_a_week, two_times_a_week, once_a_week, bi_weekly, twice_per_month, every_three_weeks, every_four_weeks, once_a_month, one_time. Example: once_a_week

first_name   string     

Client first name. Example: John

last_name   string     

Client last name. Example: Doe

email   email     

Client email. Example: mail@email.com

city   string     

Client city. Example: Latham

home_address   string     

Client street address. Example: 1494 Ben Street

state   string     

Client state (two-letter abbreviation). Example: TX

areas_to_clean   string  optional    

Areas to clean (comma-separated). Example: Front Yard, Back Yard

home_phone_number   string  optional    

Client home phone number. Example: 4155550110

cell_phone_number   string  optional    

Client cell phone number. Example: 2025550101

initial_cleanup_required   integer     

Whether the client requested an initial cleanup. Available options: 0 (no), 1 (yes). Example: 1

cleanup_notification_type   string  optional    

Cleanup notification types. Available options: off_schedule, on_the_way and completed. Example: on_the_way,completed

cleanup_notification_channel   string  optional    

Method used to notify your client. Available options: sms, email or call. Example: sms

how_heard_about_us   string  optional    

How the client heard about you. Available options: search_engine, previous_client, referred_by_family_or_friend, flier_from_business, directory_listing, social_media, vehicle_signage, radio_ad, local_event, gift_certificate, other. Example: social_media

how_heard_answer   string  optional    

Details for "how_heard_about_us". Example: Facebook

additional_comment   string  optional    

Additional client comment. Example: Please clean my yard.

credit_card_token   string  optional    

Card token from CardConnect or Stripe (credit card on file). Example: tok_5678967890678 or 678987678909876

name_on_card   string  optional    

Name on card. Example: John Doe

postal   string  optional    

Billing postal code (required for CardConnect tokens). Example: 28301

expiry   string  optional    

Expiration (required for CardConnect tokens). Example: 0924

dog_name   string[]  optional    

List of dog names (index-aligned with other dog_* arrays).

0   string  optional    

First dog name. Example: Max

1   string  optional    

Second dog name. Example: Oskar

safe_dog   string[]  optional    

Whether each dog is safe for the technician (index-aligned).

0   string  optional    

Safety for the first dog. Example: yes

1   string  optional    

Safety for the second dog. Example: no

dog_breed   string[]  optional    

List of dog breeds (index-aligned).

0   string  optional    

First dog breed. Example: Poodle

1   string  optional    

Second dog breed. Example: Bulldog

dog_comment   string[]  optional    

Notes/comments for each dog (index-aligned).

0   string  optional    

Comment for the first dog. Example: Nice and kind

1   string  optional    

Comment for the second dog. Example: Can be reactive

cross_sells   integer[]  optional    

List of cross-sell IDs selected by the client.

0   integer  optional    

First cross-sell ID. Example: 1

1   integer  optional    

Second cross-sell ID. Example: 2

2   integer  optional    

Third cross-sell ID. Example: 5

cross_sells_names   string  optional    

List of cross-sell names selected by the client. Example: Spraying,Trash bags,Premium Cleanup

coupon_code   string  optional    

Optional coupon code. Example: 5pr1nG

marketing_allowed   integer     

Client consent for promotional/marketing messages. Available options: 0 (not allowed), 1 (allowed). Example: 1

marketing_allowed_source   string  optional    

Source of the consent value (e.g. open_api, client_portal, employee_portal, wordpress). Defaults to open_api when not provided. Example: open_api

gated_community   string  optional    

Gated community. Example: 67890

gate_location   string  optional    

Gate location description. Example: left

gate_code   string  optional    

Gate code. Example: 1234

tracking_field   string  optional    

UTM tracking code. Example: utm_campaign=blog_post&utm_medium=social&utm_source=facebook

terms_open_api   integer  optional    

If you have TOS in your onboarding form. Available options: 0 (no), 1 (yes). Example: 1

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"
}
 

Request      

POST api/v2/client_on_boarding/create_client_with_package

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

email   email     

Client email. Example: john@doe.com

first_name   string     

Client first name. Example: John

last_name   string     

Client last name. Example: Doe

home_phone_number   string  optional    

Client home phone. Example: 4155550110

cell_phone_number   string  optional    

Client cell phone. Example: 2025550101

home_address   string     

Client address. Example: 1502 Morse St

city   string     

Client city. Example: New York

state   string     

Client state code. Example: TX

zip_code   string     

Client zip code. Must be a 5-digit number. Example: 12345

clean_up_frequency   string     

Client cleanup frequency. Available options are: seven_times_a_week, six_times_a_week, five_times_a_week, four_times_a_week, three_times_a_week, two_times_a_week, once_a_week, bi_weekly, twice_per_month, every_three_weeks, every_four_weeks, once_a_month, one_time. Example: once_a_week

cross_sell_id   string     

Selected package ID (id from Get packaged cross-sells). Example: 2

category   string  optional    

Organization billing option (category from Get packaged cross-sells). Example: cleanup

billing_interval   string  optional    

Organization billing interval (billing_interval from Get packaged cross-sells). Example: monthly

credit_card_token   string  optional    

Token from Card connect or Stripe for Credit card on file. Example: tok_5678967890678 or 678987678909876

name_on_card   string  optional    

Name on Card. Required when credit_card_token is provided. Example: John Doe

postal   string  optional    

Postal for Card connect credit card on file. Example: 28301

expiry   string  optional    

Expiry for Card connect credit card on file. Example: 0924

cleanup_notification_type   string  optional    

Cleanup notification types. Available options: off_schedule, on_the_way and completed. Example: on_the_way,completed

cleanup_notification_channel   string  optional    

Method used to notify your client. Available options: sms, email or call. Example: sms

how_heard_about_us   string  optional    

How the client heard about you. Available options: search_engine, previous_client, referred_by_family_or_friend, flier_from_business, directory_listing, social_media, vehicle_signage, radio_ad, local_event, gift_certificate, other. Example: social_media

how_heard_answer   string  optional    

Details for "how_heard_about_us". Example: Facebook

gated_community   string  optional    

Gated community. Example: 67890

gate_location   string  optional    

Gate location description. Example: left

gate_code   string  optional    

Gate code. Example: 1234

tracking_field   string  optional    

UTM tracking code. Example: utm_campaign=blog_post&utm_medium=social&utm_source=facebook

marketing_allowed   integer     

Client consent for promotional/marketing messages. Available options: 0 (not allowed), 1 (allowed). Example: 1

marketing_allowed_source   string  optional    

Source of the consent value (e.g. open_api, client_portal, employee_portal, wordpress). Defaults to open_api when not provided. Example: open_api

coupon_code   string  optional    

Optional coupon code. Example: 5pr1nG

terms_open_api   integer  optional    

If you have TOS in your onboarding form. Available options: 0 (no), 1 (yes). Example: 1

cross_sells_names   string  optional    

Selected package name. Example: Awesome package

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
    }
}
 

Request      

GET api/v1/leads/list

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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
    }
}
 

Request      

GET api/v1/leads/out_of_service

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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:

Supported job status values:

Supported job types:

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"
        }
    ]
}
 

Request      

GET api/v1/dispatch_board/jobs_for_date

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

date   string     

Date to load the Dispatch Board for. Format must be YYYY-MM-DD. Example: 2022-03-28

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
}
 

Request      

GET api/v2/check_token

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

token   string     

API access token - full string. Example: vUcSxeEgTgg0I65bPEgKBqU0AjBRz8cy61843egzKkI3hAcYJ9ErNYe2MTEoIEWo

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
}
 

Request      

GET api/v2/check_zip_code_multi_organizations

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

zip_code   string     

Client ZIP code. Must be a 5-digit number. Example: 12345

slugs   string[]     

List of organization slugs to check (the slug is the unique part of the onboarding URL, also returned as organization by Get organization branding info).

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.

Example request:
curl --request GET \
    --get "https://openapi.sweepandgo.com/api/v2/check_premium_organization" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}"
const url = new URL(
    "https://openapi.sweepandgo.com/api/v2/check_premium_organization"
);

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_premium_organization';
$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/check_premium_organization'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "valid": true,
    "name": "Ena adamz"
}
 

Request      

GET api/v2/check_premium_organization

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
}
 

Request      

GET api/v2/client_on_boarding/price_registration_form

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

last_time_yard_was_thoroughly_cleaned   string     

When the yard was last thoroughly cleaned. Available options are: one_week, two_weeks, three_weeks, one_month, two_months, 3-4_months, 5-6_months, 7-9_months, 10+_months. Example: one_week

clean_up_frequency   string     

Clean up frequency for the yard. Available options are: seven_times_a_week, six_times_a_week, five_times_a_week, four_times_a_week, three_times_a_week, two_times_a_week, once_a_week, bi_weekly, twice_per_month, every_three_weeks, every_four_weeks, once_a_month, one_time. Example: once_a_week

number_of_dogs   string     

Number of dogs. Example: 2

zip_code   string     

Zip code. Must be a 5-digit number. Example: 12345

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"
        }
    ]
}
 

Request      

GET api/v2/client_on_boarding/service_registration_form

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
    }
}
 

Request      

GET api/v2/client_on_boarding/organization_data

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
    }
}
 

Request      

GET api/v2/client_on_boarding/coupon_find_default

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
    }
}
 

Request      

GET api/v2/client_on_boarding/coupon_find

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

coupon_id   string     

Coupon code entered by the client (case-sensitive). Example: 5pr1nG

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
}
 

Request      

GET api/v2/client_on_boarding/check_client_email_exists

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

email   string     

Client email address. Example: john@doe.com

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>"
        }
    ]
}
 

Request      

GET api/v2/client_on_boarding/thank_you_pages

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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": ""
        }
    ]
}
 

Request      

GET api/v2/client_on_boarding/out_of_service_form

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
}
 

Request      

POST api/v2/client_on_boarding/out_of_service_form

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

name   string     

Client name. Example: Ena Doe

address   string     

Client address. Example: 1502 Morse St

email_address   string     

Client email. Example: ena@doe.com

zip_code   string     

Client zip code. Must be a 5-digit number. Example: 12345

comment   string  optional    

Client comment. Example: Demo comment

phone   string  optional    

Client phone number. Example: 2025550101

marketing_allowed   integer     

Client consent for promotional/marketing messages. Available options: 0 (not allowed), 1 (allowed). Example: 1

marketing_allowed_source   string  optional    

Source of the consent value (e.g. open_api, client_portal, employee_portal, wordpress). Defaults to open_api when not provided. Example: open_api

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"
}
 

Request      

POST api/v2/client_on_boarding/check_zip_code_exists

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

value   string     

5-digit ZIP code to check. Example: 12345

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"
}
 

Request      

GET api/v2/one_time_payment/check_invoice

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

invoice_number   string     

Invoice number (as returned by "Get invoices"). Example: 3-3-190207-2-4

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"
}
 

Request      

PUT api/v2/one_time_payment/stripe_payment

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

invoice_number   string     

Invoice number (as returned by "Get invoices"). Example: 3-3-190207-2-4

amount   string     

Amount to charge, usually the invoice_remaining value from "Check invoice status". Example: 67.98

name_on_card   string     

Client name. Example: John Doe

token   string     

Stripe card token (created with Stripe.js / Stripe Elements) — not a raw card number. Example: tok_1E0rfhHLLICwofnx4bUzDZis

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"
}
 

Request      

PUT api/v1/invoice/one_time

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

invoice_number   string     

Invoice number of the invoice being paid (as returned by "Get invoices"). Example: 3-3-190207-2-4

reference_number   string     

Payment reference, e.g. the check number. Example: ref_8798yhjasa

amount   string     

Payment amount as a decimal number in the account currency. Example: 67.98

status   string     

Payment status. Available options: successful, failed (e.g. a bounced check). Example: successful

billing_address   string  optional    

Billing address. Example: 635 Go Man Go Dr

billing_city   string  optional    

Billing city. Example: Stafford

billing_state   string  optional    

Billing state. Example: Texas

billing_zip   string  optional    

Billing zip. Example: 77477

name   string  optional    

Client name. Example: John Doe

email   string  optional    

Client email. Example: mail@mail.com

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
}
 

Request      

GET api/v2/report/count_happy_dogs

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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
}
 

Request      

GET api/v2/report/count_happy_clients

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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
}
 

Request      

GET api/v2/report/count_active_clients

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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
}
 

Request      

GET api/v2/report/jobs_count

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
        }
    ]
}
 

Request      

GET api/v2/report/staff_select_list

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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
        }
    ]
}
 

Request      

GET api/v2/report/route_planning_report

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

date   string     

The route date in YYYY-MM-DD format. Example: 2026-09-21

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:

Possible job types:

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
        }
    ]
}
 

Request      

GET api/v2/report/completed_jobs_report

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

date   string  optional    

Filter jobs for a specific date. Must be today or in the past. Format: YYYY-MM-DD. Example: 2026-07-13

date_from   string  optional    

Start date for the report. Required when date is not provided. Must be today or in the past. Format: YYYY-MM-DD. Example: 2026-01-01

date_to   string  optional    

End date for the report. Required when date is not provided. Must be on or after date_from and cannot be in the future. Format: YYYY-MM-DD. Example: 2026-01-31

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"
}
 

Request      

POST api/v2/gift_card

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

purchaser_name   string     

Purchaser name. Example: John Doe

purchaser_email   string     

Purchaser email. Example: jon@doe.com

purchaser_phone   string  optional    

Purchaser phone. Example: 2025550101

amount   decimal     

Gift certificate amount. Example: 12.45

expires   string  optional    

Gift certificate expiration date (in format: Y-m-d). Example: 2024-12-23

bought   string     

Purchase date of the gift certificate (in format: Y-m-d). Example: 2024-11-23

reference_number   string     

Unique reference number of the gift certificate (e.g. external order/payment ID). Example: 12c45-wa3B

recipient_name   string     

Recipient name. Example: Jane Doe

recipient_email   string  optional    

Recipient email. Example: jane@doe.com

special_note   string  optional    

Special note. Example: For your birthday

name_on_card   string  optional    

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"
    }
}
 

Request      

POST api/v2/coupon

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

coupon_id   string  optional    

Coupon code clients will enter. Example: 5pr1nG

name   string  optional    

Coupon name. Example: Spring Season

coupon_type   string     

Coupon type. Available options: percent, amount. Example: amount

duration   string     

How long the discount applies. Available options: once (first invoice only), forever, repeating (for number_of_months). Example: repeating

percent_off   string  optional    

Percent discount (max 100). Required if coupon_type is percent. Example: 20

amount_off   string  optional    

Amount discount. Required if coupon_type is amount. Example: 22.51

redeem_by   string  optional    

Date when coupon expires (in format: Y-m-d). Example: 2024-12-23

max_redemptions   integer  optional    

How many subscriptions can use this coupon. Example: 5

number_of_months   integer  optional    

How many months the discount is applied. Required if duration is repeating; minimum 2. Example: 2

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"
        }
    ]
}
 

Request      

GET api/v2/free_quotes

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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"
}
 

Request      

POST api/v2/text-inbound/on-the-way/check-dogs

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

From   string     

SMS sender number. Example: 12025550102

To   string     

SMS recipient number. Example: 12025550101

SmsMessageSid   string     

Message id. Example: 89iwieweow8e49038408902

Body   string     

If staff can enter or not. Available options: ENT (Enter), DNE (Do Not Enter). Example: ENT

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"
}
 

Request      

POST api/v2/text-twilio/on-the-way/webhook

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

status   string     

Message delivery status. Example: delivered

job_id   string     

Job number. Example: 123

client   string     

Client unique id. Example: cus_9is0ia893

chanel   string     

Channel through which the client received the message. Example: sms

type   string     

Message type. Example: on_the_way

staff_id   integer     

ID of the staff member who sent the message. Example: 1

local_message_id   string  optional    

Unique string for each message from field tech portal. Example: 270444-10-1753266841837

message_id   string  optional    

Unique string for each message from Twilio. Example: SM4a13b79c2b6a0e17bb77b6c0ce0d4a34

error_code   integer  optional    

Error code from Twilio. Example: 1

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"
}
 

Request      

GET api/v2/packages_list

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

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:

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"
    ]
}
 

Request      

GET api/v1/webhooks/index

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"
    ]
}
 

Request      

GET api/v1/webhooks/list

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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"
    ]
}
 

Request      

PUT api/v1/webhooks/retry

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

id   string     

The id of a previously triggered webhook, as returned by "List triggered webhooks". Example: e0e03073-a1a3-4f6e-82ff-81dab3772534

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
    }
}
 

Request      

GET api/v2/invoices

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer     

Page number. Must be at least 1. Example: 1

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 10. Example: 20

type   string     

Type of invoices to return. Available options: recurring, one_time. Example: recurring

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
    }
}
 

Request      

GET api/v2/payments

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Page number. Must be at least 1. Defaults to 1. Example: 1

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 10. Example: 20

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
    }
}
 

Request      

GET api/v2/subscriptions

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Page number. Must be at least 1. Defaults to 1. Example: 1

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 10. Example: 20

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
    }
}
 

Request      

GET api/v2/commercial/subscriptions

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Page number. Must be at least 1. Defaults to 1. Example: 1

length   integer  optional    

Number of records per page. Must be between 1 and 50. Defaults to 10. Example: 20

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
    }
}
 

Request      

GET api/v2/commercial_clients/active

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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
    }
}
 

Request      

GET api/v2/commercial_clients/inactive

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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
    }
}
 

Request      

GET api/v2/commercial_clients/with_subscription

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Query Parameters

page   integer  optional    

Get results for specific page. Example: 2

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
    }
}
 

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"
                }
            ]
        }
    ]
}
 

Request      

POST api/v2/commercial_clients/client_details

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Body Parameters

client   string     

Unique commercial client identifier in your organization (the client field returned by the commercial client list and search endpoints). Example: cc_MTPQPRUUUY7G