Skip to content

Overview

Everything your organization has on the dashboard — its webinars, their sessions, registrations and ratings, its VSLs, the sales counted to them, its surveys and their responses, its pages, its webhooks — is read and, where it makes sense, written through the public API, so your own systems and the tools you wire together can work with it.

https://api.sparkwebinar.io/public/v1

Every request carries your organization’s API token as a bearer:

Authorization: Bearer <token>

The token is on the dashboard, under Settings, for owners and managers, and can be generated anew there — the old one stops working at once. The token names the organization, so no route does: everything you read and write is your organization’s, and anything else is answered as not found.

Status infoCode Why
401 UNAUTHENTICATED No bearer in the request, or a header not of that form.
401 API_TOKEN_INVALID A token that names no organization — generated anew since, or never ours.
403 ORGANIZATION_UNAVAILABLE The organization is not served — suspended, locked, or with no plan.

Call it from a server. There is no CORS on the public API: a page in a browser cannot call it, and should not — the token would be in the page.

Every answer is JSON in the same envelope. The status is on the wire; the body is data, and metadata where there is more to say.

{ "data": { "id": 12, "name": "Launch webinar", "..." : "..." } }

A list answers a page of items, and in metadata.list the page it is and how many there are in all:

{
"data": [ { "id": 41, "...": "..." }, { "id": 40, "...": "..." } ],
"metadata": { "list": { "pagination": { "page": 1, "size": 20 }, "total": 57 } }
}

A failure is data: null, and an infoCode where there is one to give:

{ "data": null, "metadata": { "infoCode": "WEBINAR_NOT_FOUND" } }
Status infoCode Why
400 VALIDATION_FAILED A body, a query string or an id that does not fit the route.
404 <RESOURCE>_NOT_FOUND Nothing of your organization’s by that id — WEBINAR_NOT_FOUND, WEBINAR_REGISTRATION_NOT_FOUND, SURVEY_NOT_FOUND, SURVEY_RESPONSE_NOT_FOUND, CUSTOM_PAGE_NOT_FOUND, ORGANIZATION_WEBHOOK_NOT_FOUND, WEBINAR_TICKET_ORDER_NOT_FOUND, AB_TEST_NOT_FOUND, VSL_NOT_FOUND.
409 … The request is well-formed and cannot be done as things are; each route says its codes.
429 TOO_MANY_REQUESTS Over the limit below.

A route that deletes answers 200 with data: null.

A list takes its page in the query string: page, from 1, and size, up to 100 — twenty by default. Its filters go beside them, each a query parameter named after the field it narrows by; a filter not sent is not applied. Text filters such as a name or an e-mail match inside the value, whatever the case. An instant is filtered as a span: …From is on or after it, …To before it, either alone or both. Every list is newest first, but a webinar’s sessions, which are in the order they start.

GET /public/v1/webinar-registrations?webinarId=12&createdAtFrom=2026-10-01T00:00:00Z&size=100&page=2

Every id is a whole number. Every instant is an ISO 8601 string in UTC, 2026-11-03T22:00:00.000Z, and is sent the same way — with an offset, if not Z.

Every organization may make 120 requests a minute, over the whole public API, whatever its plan. Each answer says where you stand:

Header What it says
X-RateLimit-Limit The limit, 120.
X-RateLimit-Remaining How many are left in this minute.
X-RateLimit-Reset Seconds until the minute turns over.

Over it, the answer is 429 with TOO_MANY_REQUESTS and a Retry-After in seconds. Reading a list in pages of 100 stays well under it.