API Changelog
Last updated: August 8, 2026
Below is a log of changes to Switchboard's Public API. For getting set up and full documentation on the API, visit: https://api.oneswitchboard.com/v1/docs
For any feedback or questions, please email developers@oneswitchboard.com.
August 7th, 2026
This month we've been investing heavily to make more of what you do on Switchboard possible through the API and SQL Mirror. We added dozens of new API endpoints, webhooks, and SQL Mirror tables to enable greater automation of your workflows across Count On Me forms and contributions, saved searches, phone and email lists, webhook management, canned responses, keywords, shortlink domains, messaging clients, email senders, billing, and organization details. Here's what's new in the API.
Check out the SQL Mirror Changelog to see the newly available fields and tables from the push.
Webhooks
Manage Webhook Endpoints via the API
You can now manage endpoint configuration, auth settings, enabled state, and event subscriptions programmatically instead of only through the UI. List, retrieve, create, and update webhook endpoints via GET /v1/webhooks, GET /v1/webhooks/{webhook_id}, POST /v1/webhooks, and PATCH /v1/webhooks/{webhook_id}.
Key behaviors:
Subscriptions accept individual event types,
*, and version-specific wildcard types likebroadcast.*; values are validated against the endpoint’sversion.Secrets stay write-only: responses never return the webhook password, and instead expose whether one is configured.
Delete is not supported through the public API; use
PATCH /v1/webhooks/{webhook_id}to updateis_enabledinstead.
See Webhooks section in the API docs for more details and the full list of event types.
Count On Me
Forms & Form Responses
You can now fully manage forms through the API. You can create and edit forms (/v1/forms), and move a form through its entire lifecycle:
publish (
/v1/forms/{form_id}/publish)unpublish (
/v1/forms/{form_id}/unpublish)close (
/v1/forms/{form_id}/close)archive (
/v1/forms/{form_id}/archive)
You can also:
duplicate forms within or across organizations (
/v1/forms/{form_id}/duplicate)create and read CSS templates (
/v1/form_css_templates)pull performance stats (
/v1/forms/{form_id}/performance)read form responses (
/v1/form_responses)
Key behaviors:
Any user can create a basic form to collect survey responses, opt-ins, etc. Creating a contribution form to process payments first requires Stripe onboarding in the UI.
Contributions
You can now read your Count On Me contribution data and manage recurring gifts through the API: contributions (/v1/contributions), payouts (/v1/contributions_payouts), and disputes (/v1/contributions_disputes), plus canceling or editing recurring contributions (/v1/recurring_contributions/{recurring_contribution_id}/cancel and /v1/recurring_contributions/{recurring_contribution_id}).
Key behaviors:
The public mutate API only supports editing a recurring contribution to a lesser frequency or lesser amount. To make a recurring gift larger or more frequent, have your donor contact support@countonme.org.
See the Forms and Contributions sections in the API docs for more details.
Saved Searches
Editing & Coverage
You can now update an existing Saved Search via
PATCH /v1/saved_searches/{saved_search_id}, editing the samecriteria.include.filtersyou'd set on create. Because saved searches are dynamic queries over your phones and emails, the updated criteria take effect the next time the search is evaluated. Any scheduled Broadcast or Email Blast using it as its audience will send to the refreshed set. Edits sync both ways with the Switchboard UI.All Saved Search filters are now available via API, allowing you to create any complex Saved Search criteria directly via the API
Added the Location Filter which allows you to search by state, area code, time zone, zip code, or zip code radius
Added the Field Filter which allows you to filter based on
sb_custom_scoreorsb_custom_sourceAdded the Form Filter which allows you to filter based on whether contacts have submitted responses to particular forms.
Cross-Org and Collective Sharing
You can now build saved searches that match contacts shared with your organization, or opted out/unsubscribed across shared organizations, using the new shared_phones, shared_emails, shared_optouts, and collective_optouts filter kinds in the filters field on POST /v1/saved_searches.
Key behaviors:
shared_phones/shared_emailsmatch phone or email contacts also present in one or more organizations that share data with yours;shared_optoutsmatches opt-outs/unsubscribes across those same shared orgs. All three require at least one active incoming data share, and any organization IDs you specify must each have an active data share with your orgcollective_optoutsmatches opt-outs/unsubscribes across all Switchboard Collective member organizations. It requires Collective membership and does not support targeting individual organizationsshared_optoutsandcollective_optoutsaccept an optional occurrences filter to require a minimum/maximum number of opt-out occurrences
See the Create Saved Search section in the API docs for more details.
Phone Lists
Added an endpoint to update a phone list's name, description and acquisition cost at PATCH /v1/phone_lists/{phone_list_id}
Organizations
You can now list the organizations your API key has access to, or retrieve a single one by ID, with GET /v1/organizations and GET /v1/organizations/{organization_id}.
Billing
You can now fetch and pay invoices via /v1/invoices and /v1/invoices/pay, and payment methods via /v1/payment_methods
Canned Responses
You can now list and retrieve canned responses configured in your org via GET /v1/canned_responses and GET /v1/canned_responses/{id}.
See Canned Responses section in the API docs for more details.
Messaging Clients
You can now list and retrieve messaging clients in your org and update Sticky Sender settings via GET /v1/messaging_clients and GET /v1/messaging_clients/{id}.
See Messaging Clients section in the API docs for more details.
Email Senders
You can now list and retrieve email senders used as the "from" address on email blasts via GET /v1/email_senders and GET /v1/email_senders/{email_sender_id}.
Key behaviors:
Fields include name, email, enabled status, and creation/modified timestamps
See Email Senders section in the API docs for more details.
Shortlink Domains
You can now list, retrieve, and manage the domains configured for shortlinks in your org: GET /v1/shortlink_domains and GET /v1/shortlink_domains/{domain_id} for reads, plus endpoints to set a domain as primary and archive/unarchive domains .
Key behaviors:
List supports filtering by organization, primary status, and
archived_at(null/not-null/timestamp comparisons); by default excludes archived domains, but only when no other filter is supplied — passing any other filter includes archived domains tooSetting a domain as primary automatically demotes the org's previous primary domain
An archived domain can't be set as primary — unarchive it first
Bulk archive is supported (capped at the standard page size); bulk unarchive is not yet available
See Shortlink Domains section in the API docs for more details.
Uploaded Media
You can now retrieve a single uploaded media object in your org via GET /v1/uploaded_media/{uploaded_media_id}.
See Uploaded Media section in the API docs for more details.
Keywords
You can now list and retrieve keyword-triggered auto-replies configured in your org via GET /v1/keywords and GET /v1/keywords/{keyword_id}.
See Keywords section in the API docs for more details.
July 28, 2026
Bulk Label Updates via CSV Upload
Added new endpoints to update multiple labels across multiple contacts in a single async request, replacing the need to loop the single-phone update_labels endpoint or upload separate phone lists per label.
New flow:
Upload your CSV to a presigned URL via a new
POST /v1/uploadsCSV format: Three columns
phone_number,label,action(addorremove). Repeat a phone number across rows to apply multiple labels to the same contact.
Kick off the bulk-label job (via
POST /v1/phones/bulk_update_labels) referencing that uploadPoll
GET /v1/jobs/{job_id}for status until complete
Key behaviors:
Label references: Labels can be referenced by name or public ID (
lb_...); the system detects which. Names that don't yet exist are created onadd; unknown label IDs are skipped.Existing phones only: Phone numbers not found in your organization are skipped. Use
POST /v1/phone_liststo add phones to your organization in bulk, orPOST /v1/phonesto add phones one by one.Supported actions:
addandremoveare supported.replaceis not currently available.Upload validation: When
bulk_update_labelsis called, the referenced upload is validated. Requests referencing a missing or expired upload return a400.Job status: Jobs return
COMPLETEDorERRORvia the poll endpoint. Per-record failure details not currently surfaced in the response.Concurrent job cap: Subject to the same 20-job in-flight cap that applies to other async endpoints.
Existing endpoints unchanged: The single-phone
POST /v1/phones/update_labelsendpoint and phone-list label updates continue to work as before.
July 8, 2026
Update, Pause, Resume, and Sample Send Broadcasts
You can now update, pause, resume, and send a sample broadcasts via the API, expanding broadcast management alongside the existing create, schedule, and send endpoints.
Update a broadcast — Use PATCH /v1/broadcasts/{broadcast_id} to edit a broadcast's title, message text, description, audience, scheduled time, opt-out setting, and attached media. The endpoint uses three-state PATCH semantics: a field set to a value updates it, a field set to null clears it back to default, and a field omitted from the request is left unchanged.
What you can edit depends on the broadcast's status:
Draft: Every field, including audience and scheduled time.
Scheduled: Every field, except schedule time and audience (
phone_list_idandsaved_search_id).Paused: Content only (title, message text, description, and the add-opt-out-text setting). Audience and scheduled time can't be changed, and edits apply only to messages that haven't been sent yet.
Sending, Sent, Stopped, or Error: Read-only. To edit a sending broadcast, pause it first.
Pause a broadcast — Use POST /v1/broadcasts/{broadcast_id}/pause with an empty body to pause a broadcast that is currently sending. The response returns the updated broadcast with a paused status. While paused, you can edit the broadcast's content (see above) and then resume or stop it.
Resume a broadcast — Use POST /v1/broadcasts/{broadcast_id}/resume with an empty body to resume a paused broadcast. The response returns the updated broadcast with a sending status, and delivery continues with any unsent messages.
Send a sample of a broadcast — Use POST /v1/broadcasts/{broadcast_id}/send_sample to send sample messages to specific phone numbers and see how a broadcast renders before sending it to your full audience. Samples render using random contact data from the broadcast's audience, so the broadcast must currently have an audience (a phone list or saved search) set.
June 15, 2026
Rate Limits & Concurrent Job Caps on Export and Create List Endpoints
We've added new rate limits and concurrent job caps on our heaviest endpoints, exports and list populates, to keep the API responsive for everyone. These apply in addition to the existing global limit of 300 requests per minute across all endpoints.
Per-minute rate limits:
Exports (shared across all 12 export endpoints): 60 requests per minute per key, 20 per organization.
List creates (shared across both list-create endpoints): 20 requests per minute per key, 8 per organization.
Concurrent job caps: These limit how many jobs you can have in flight at once. Unlike the per-minute limits, they aren't time-based, capacity frees up as your running jobs finish.
Exports: 20 in-flight jobs per key, 4 per organization.
List creates: 20 in-flight jobs per key, 4 per organization.
When you hit a per-minute limit: You'll get a 429 response with a Retry-After header (seconds to wait before the next window) and a rate_limited error code in the body. There are no X-RateLimit-* headers, so pace your requests against the limits above.
If these limits are a problem for your use case, reach out to developers@oneswitchboard.com.
June 2, 2026
Saved Searches — Engagement Filters
Added support to the API for creating Saved Searches that filter by message engagement, including delivery, clicks, replies, donations, opens, etc. This includes all kinds of engagement filters: engagement, shared_engagement, and collective_engagement.
Filters created via the API are viewable and editable in the Switchboard UI, and vice versa. Shorthand match modes provide the same engagement options as the UI e.g. clicked_but_did_not_donate. See criteria.include.filters.kind in the full documentation for details.
May 28, 2026
One-Off Message Replies
You can now send a single SMS to an existing contact via the public API. Use POST /v1/phones/{phone_number}/messages to send a one-off message outside of a broadcast.
Key behaviors:
Contact must exist — The contact must already exist in your organization. There is no auto-creation of contacts from phone numbers.
Exact text required — Supply the full message body. Templates and custom fields (e.g.
{{ sb_first_name }}) are not supported.Media — Attach media using the
media_idfield (upload first viaPOST /v1/uploaded_media).Rate limited — 60 requests per minute per organization.
Visibility — Sent messages appear in All Threads and are threaded with existing conversation history for that number.
Delivery status — The POST response contains initial status. Check final delivery status via
GET /v1/phones/{phone_number}/messages.
May 12, 2026
Multi-Organization API Keys
A single API key can now have access to multiple organizations. This is intended for users who manage multiple organizations and previously needed a separate key for each. Keys scoped to a single organization continue to work as they do today, no changes required.
New behavior for keys with access to multiple organizations:
Reading data — List endpoints automatically return results from all organizations your key can access. Use the
organization_idfilter to narrow results to a specific organization (see Filtering).Creating resources — When making a create/POST request with a multi-organization key, you must include the
organization_idfield in the request body to specify which organization the resource belongs to. Single-organization keys do not require this field.Checking your access — Call
GET /v1/whoamito see which organizations your key can access and what roles it has in each.
Managing access:
Key creators can add organizations to a key from Account Settings. Only the key creator can add organizations.
Organization admins will see a label on any key with access to their organization from Organization Settings, and can remove their organization's access at any time.
Apr 29, 2026
List SQL Mirror Datasets
Added GET /v1/sql_mirror_datasets to list all SQL mirror datasets available to your API key. For multi-organization keys, this returns datasets across all organizations the key can access. For single-organization keys, it returns a list with one entry.
Each dataset in the response includes organization_id, bigquery_dataset, bigquery_project, and fully_qualified_name (e.g. switchboard-mirror.jane_for_congress).
Use the organization_id filter to narrow results to a specific organization. See full documentation for details.
Apr 7, 2026
Phone Lookup and Messages Added GET /v1/phones/{e164_number} to look up a phone's metadata by E.164 number, and GET /v1/phones/{e164_number}/messages to retrieve the full conversation history of messages between that phone number and your organization. These endpoints support integrations that need to look up contact details or message history from a phone number directly. Note that these are beta endpoints and responses are subject to change.
Email Blast Content Added optional html_content and text_content fields to the Email Blast endpoints. Pass include_html_content=true or include_text_content=true as query parameters to include them in the response.
New Fields on Phone and Email Lists Added city and street_address as available fields when creating phone lists and email lists.
Phone Message Fields Added message_direction, received_at, and is_phone_opted_out to phone message payloads within a "List Broadcast Phone Messages" response.
Label Name Validation Label names are now validated to a maximum of 255 characters. Requests with longer names will return a 400 error.
Mar 5, 2026
Fix list endpoints pagination filter preservation
next_page_url in list payloads now preserve filter= query parameter expressions
Jan 20, 2026
Create and Send Broadcasts
Added support to create and send text broadcasts directly via the API. The expected flow is:
Create Audience (Search or List) → Upload Media (optional) →
Create Broadcast → Preview Broadcast → Schedule/Send Broadcast
Upload Media
Added new endpoints to upload text, video, contact cards, and more to Switchboard, and to retrieve your media library via the API. This can be used along with the broadcast endpoints to send MMS texts with media.
Saved Searches
Creating a Search
You can now create Saved Searches via the API. Due to the complexity of validating the input and ensuring all combinations work correctly, we will be rolling out support for various filter types over time. See criteria.include.filters.kind in the documentation for a full list of supporter filter kinds. As part of the initial change, we support:
Donation filters
Optouts & Unsubscribe filters
Label filters
New to Universe filters
Audience filters (including other lists or sesarches)
Carrier filters (for phone searches)
Domain filters (for email searches)
Group filters (finding any or all matches among a set of other filters)
Refreshing a Search
We've added support for triggering a refresh of an existing search via the API, or converting the search into a static list. This can be used to ensure that evaluations happen on a particular cadence that matches your organization's needs.
September 2, 2025
Updating Error Code Details
Updated the phone messages endpoint to include the Switchboard error code and error message, the provider error code, the provider error details (JSON details about the error), and in cases where we skipped sending a message, the skip reason.
August 27, 2025
Documentation Update
Updated documentation at https://api.oneswitchboard.com/v1/docs to include more example sample code, including in Python.
August 25, 2025
Saved Search Endpoints
Added the ability to Export a Saved Search, including options to configure which fields to include in the CSV.
August 20, 2025
Export Phones and Export Emails
Added the ability to customize exports for All Phones and All Emails, to configure which fields to include in the CSV.
Saved Search Endpoints
Added the ability to Refresh a Saved Search, and Convert a Saved Search to a List.
August 12, 2025
Saved Search Endpoints
Added the ability to list and retrieve Saved Searches within your organization. This includes the ability to filter and search for specific searches by specific criteria.
See documentation about Filtering for more details on how to structure those requests.