Skip to content
Coritan Docs

Client API: Wicket

Wicket checks that a person is filling in a form.

View as Markdown

Wicket checks that a person is filling in a form. Make widgets and read how they do: their hostnames, modes, secret keys and the numbers over time. Your server verifies a token the widget puts in the form with the secret key.

Base URL: https://api.coritan.com/api/v1. Paths below are complete.

To try these requests in the browser, open the interactive Client API reference.

Method Path Summary
GET /api/v1/client/wicket/summary Widgets summary
GET /api/v1/client/wicket/widgets List your widgets, with how each did in the last 24 hours and why any needs a look
POST /api/v1/client/wicket/widgets Add a widget
GET /api/v1/client/wicket/widgets/{widget_id} Get widget
PATCH /api/v1/client/wicket/widgets/{widget_id} Change a widget's name, hostnames, mode, appearance or branding
DELETE /api/v1/client/wicket/widgets/{widget_id} Delete a widget
GET /api/v1/client/wicket/widgets/{widget_id}/analytics Widget analytics
POST /api/v1/client/wicket/widgets/{widget_id}/secret Make a new secret key for a widget
POST /api/v1/wicket/feedback Tell Wicket what a passed check turned out to be
POST /api/v1/wicket/siteverify Check a token the widget put in your form

GET /api/v1/client/wicket/summary

A short summary of Wicket on your account: how many widgets you have and your plan's limit, the checks started and passed in the last 24 hours, and each widget that needs a look with the reason.

Authentication: an access token, sent as Authorization: Bearer <token>.

Status Meaning
200 Success.

Fields of a 200 response:

Field Type Description
widgets integer
limit integer How many widgets your plan allows. -1 is unlimited.
issued_24h integer
passed_24h integer
solve_rate_24h number or null
attention array of AttentionItem
attention[].widget_id integer
attention[].name string
attention[].reason string disabled, not_verifying or hostname_refused.
attention[].disabled_reason string or null For the disabled reason only: why our team turned the widget off. Null for the other reasons.

List your widgets, with how each did in the last 24 hours and why any needs a look

Section titled List your widgets, with how each did in the last 24 hours and why any needs a look

GET /api/v1/client/wicket/widgets

List your widgets, with how each did in the last 24 hours and why any needs a look.

The answer holds one page, how many widgets match over every page, how many widgets your plan allows, and the totals for your whole account.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required Description
q query string or null no Only widgets whose name, site key or one of whose hostnames contains this text, ignoring case.
status query string no Which widgets to list: all (the default), active, disabled (turned off by our team) or attention (disabled, not verifying tokens, or refused for a hostname). Any other word answers 422. Default: all.
sort query string no The order: name, created, challenges (in the last 24 hours) or solve_rate (in the last 24 hours), each with a leading - for descending. The default is -created, newest first. A widget with no challenges in 24 hours has no solve rate and comes last. Any other word answers 422. Default: -created.
page query integer no The page, starting at 1. Default: 1.
per_page query integer no Widgets on a page, at most 100. Default: 24.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
items array of WidgetSummary
items[].id integer
items[].name string
items[].site_key string The public key your page puts in the widget. It starts with wk_.
items[].mode string managed, non_interactive or invisible.
items[].status string active, or disabled when our team turned the widget off.
items[].branded boolean Whether you chose to show Wicket's name on the widget.
items[].hostnames array of string The first three hostnames. hostname_count is how many the widget lists.
items[].hostname_count integer
items[].created_at string
items[].last_challenge_at string or null When the widget last started a challenge, to the minute.
items[].stats_24h Stats24h
items[].attention array of string Why the widget needs a look, if it does: disabled (our team turned it off), not_verifying (20 or more passes in 24 hours and your server verified none) or hostname_refused (a challenge came from a page whose hostname the widget does not list).
items[].disabled_reason string or null Why our team turned the widget off, or null when it is not turned off.
total integer How many widgets match q and status, over every page.
page integer
per_page integer
limit LimitUsed
limit.used integer
limit.limit integer -1 is unlimited.
stats ListStats
stats.issued_24h integer
stats.passed_24h integer
stats.solve_rate_24h number or null
stats.attention array of AttentionItem Every widget of the account that needs a look, one entry for each reason, not only the widgets on this page.

POST /api/v1/client/wicket/widgets

Add a widget. The answer holds the widget and its secret key, which is shown once and cannot be read again, so save it now.

Answers 402 when your plan has no room for another widget, for that many hostnames on one widget, or for turning Wicket's name off. Answers 422 for a name, mode, hostname or appearance setting Wicket refuses, and the message names it.

Authentication: an access token, sent as Authorization: Bearer <token>.

application/json (required)

Field Type Required Description
name string yes What the widget is for, 1 to 100 characters.
hostnames array of string yes The hostnames the widget works on, such as example.com. A hostname also covers every name under it, so example.com covers www.example.com.
mode string no managed, non_interactive or invisible.
appearance object or null no Any of theme (auto, light, dark), size (normal, flexible, compact) and language (auto or a code such as "es").
branded boolean no Show Wicket's name on the widget. Turning it off needs a plan that includes widgets without Wicket's name.
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

Fields of a 201 response:

Field Type Description
widget WidgetDetail
widget.id integer
widget.name string
widget.site_key string The public key your page puts in the widget. It starts with wk_.
widget.mode string managed, non_interactive or invisible.
widget.status string active, or disabled when our team turned the widget off.
widget.branded boolean Whether you chose to show Wicket's name on the widget.
widget.hostnames array of string Every hostname the widget lists.
widget.hostname_count integer
widget.created_at string
widget.last_challenge_at string or null When the widget last started a challenge, to the minute.
widget.stats_24h Stats24h
widget.attention array of string Why the widget needs a look, if it does: disabled (our team turned it off), not_verifying (20 or more passes in 24 hours and your server verified none) or hostname_refused (a challenge came from a page whose hostname the widget does not list).
widget.disabled_reason string or null Why our team turned the widget off, or null when it is not turned off.
widget.appearance Appearance The theme, size and language the widget uses when the page sets none.
widget.secret_prefix string The start of the secret key, to tell keys apart. The rest is never shown again.
widget.secret_rotated_at string or null
widget.previous_secret_expires_at string or null When the secret key you replaced stops working, while a rotation's grace period is running.
widget.limits Limits What your plan allows: {"hostnames": 10} is the most hostnames one widget lists.
widget.embed Embed
secret string The secret key. It is shown once, so save it now.

GET /api/v1/client/wicket/widgets/{widget_id}

Read one widget: every hostname, its appearance, the start of its secret key, your plan's hostname limit and the script and verify addresses to use.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
widget_id path integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
id integer
name string
site_key string The public key your page puts in the widget. It starts with wk_.
mode string managed, non_interactive or invisible.
status string active, or disabled when our team turned the widget off.
branded boolean Whether you chose to show Wicket's name on the widget.
hostnames array of string Every hostname the widget lists.
hostname_count integer
created_at string
last_challenge_at string or null When the widget last started a challenge, to the minute.
stats_24h Stats24h
stats_24h.issued integer Challenges Wicket started for the widget in the last 24 hours.
stats_24h.passed integer Challenges a visitor passed in the last 24 hours.
stats_24h.failed integer Challenges a visitor failed in the last 24 hours.
stats_24h.solve_rate number or null passed divided by issued, or null when nothing was issued.
attention array of string Why the widget needs a look, if it does: disabled (our team turned it off), not_verifying (20 or more passes in 24 hours and your server verified none) or hostname_refused (a challenge came from a page whose hostname the widget does not list).
disabled_reason string or null Why our team turned the widget off, or null when it is not turned off.
appearance Appearance The theme, size and language the widget uses when the page sets none.
secret_prefix string The start of the secret key, to tell keys apart. The rest is never shown again.
secret_rotated_at string or null
previous_secret_expires_at string or null When the secret key you replaced stops working, while a rotation's grace period is running.
limits Limits What your plan allows: {"hostnames": 10} is the most hostnames one widget lists.
embed Embed
embed.script_url string or null The script your page loads.
embed.siteverify_url string The address your server posts the token and the secret key to.

Change a widget's name, hostnames, mode, appearance or branding

Section titled Change a widget's name, hostnames, mode, appearance or branding

PATCH /api/v1/client/wicket/widgets/{widget_id}

Change a widget's name, hostnames, mode, appearance or branding. Send only what changes; hostnames is the complete new list.

Answers 402 when the new hostnames pass your plan's limit for one widget, or when you turn Wicket's name off on a plan that does not include it. Answers 422 for a value Wicket refuses, and the message names it.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
widget_id path integer yes

application/json (required)

Field Type Required Description
name string or null no The new name, 1 to 100 characters.
hostnames array of string or null no The complete list of hostnames. It replaces the current list.
mode string or null no managed, non_interactive or invisible.
appearance object or null no Any of theme, size and language. A setting you leave out keeps its value.
branded boolean or null no Show Wicket's name on the widget.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
id integer
name string
site_key string The public key your page puts in the widget. It starts with wk_.
mode string managed, non_interactive or invisible.
status string active, or disabled when our team turned the widget off.
branded boolean Whether you chose to show Wicket's name on the widget.
hostnames array of string Every hostname the widget lists.
hostname_count integer
created_at string
last_challenge_at string or null When the widget last started a challenge, to the minute.
stats_24h Stats24h
stats_24h.issued integer Challenges Wicket started for the widget in the last 24 hours.
stats_24h.passed integer Challenges a visitor passed in the last 24 hours.
stats_24h.failed integer Challenges a visitor failed in the last 24 hours.
stats_24h.solve_rate number or null passed divided by issued, or null when nothing was issued.
attention array of string Why the widget needs a look, if it does: disabled (our team turned it off), not_verifying (20 or more passes in 24 hours and your server verified none) or hostname_refused (a challenge came from a page whose hostname the widget does not list).
disabled_reason string or null Why our team turned the widget off, or null when it is not turned off.
appearance Appearance The theme, size and language the widget uses when the page sets none.
secret_prefix string The start of the secret key, to tell keys apart. The rest is never shown again.
secret_rotated_at string or null
previous_secret_expires_at string or null When the secret key you replaced stops working, while a rotation's grace period is running.
limits Limits What your plan allows: {"hostnames": 10} is the most hostnames one widget lists.
embed Embed
embed.script_url string or null The script your page loads.
embed.siteverify_url string The address your server posts the token and the secret key to.

DELETE /api/v1/client/wicket/widgets/{widget_id}

Delete a widget. Its site key and secret key stop working at once, so a form that uses the widget stops passing.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
widget_id path integer yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
status string

GET /api/v1/client/wicket/widgets/{widget_id}/analytics

The numbers of one widget over a range: a point for each hour when the numbers cover 7 days or less, or for each day when they cover more, the totals with how many tokens your server verified, and the top ten hostnames, actions, countries, browsers and operating systems.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required Description
widget_id path integer yes
range query string no How far back to read: 24h (the default), 7d, 30d, 90d or 365d. A range longer than your plan reads back is not refused: the answer covers the days your plan allows, says clamped is true and names the plan that allows the range in upgrade. Any other word answers 422. Default: 24h.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
range string The range you asked for.
from string The start of the span the numbers cover.
to string
granularity string hour when the numbers cover 7 days or less, day when they cover more (30, 90 and 365 days).
allowed_days integer How many days back your plan reads.
clamped boolean True when the range is longer than your plan allows, so the numbers cover allowed_days only.
upgrade Upgrade or null Set when clamped: the plan that allows the range you asked for.
upgrade.plan string or null The plan that allows the range you asked for, such as plan-pro.
series array of SeriesPoint
series[].t string
series[].issued integer
series[].passed integer
series[].passed_interactive integer
series[].failed integer
series[].interactive_shown integer
totals AnalyticsTotals
totals.issued integer
totals.passed integer
totals.passed_interactive integer
totals.failed integer
totals.interactive_shown integer
totals.unsolved integer issued minus passed minus failed: challenges nobody finished.
totals.solve_rate number or null
totals.verify VerifyTotals
top AnalyticsTop
top.hostname array of TopRow
top.action array of TopRow
top.country array of TopRow
top.browser array of TopRow
top.os array of TopRow

Make a new secret key for a widget

Section titled Make a new secret key for a widget

POST /api/v1/client/wicket/widgets/{widget_id}/secret

Make a new secret key for a widget. The answer holds it once, so save it now.

With grace set to 2h the old secret key keeps working for 2 hours, so you can change your server without a gap. With none it stops at once. Any other value answers 422. We email the account owner when a secret key is rotated.

Authentication: an access token, sent as Authorization: Bearer <token>.

Name In Type Required
widget_id path integer yes

application/json

Field Type Required Description
grace string no 2h keeps the old secret key working for 2 hours. none stops it at once.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type Description
widget WidgetDetail
widget.id integer
widget.name string
widget.site_key string The public key your page puts in the widget. It starts with wk_.
widget.mode string managed, non_interactive or invisible.
widget.status string active, or disabled when our team turned the widget off.
widget.branded boolean Whether you chose to show Wicket's name on the widget.
widget.hostnames array of string Every hostname the widget lists.
widget.hostname_count integer
widget.created_at string
widget.last_challenge_at string or null When the widget last started a challenge, to the minute.
widget.stats_24h Stats24h
widget.attention array of string Why the widget needs a look, if it does: disabled (our team turned it off), not_verifying (20 or more passes in 24 hours and your server verified none) or hostname_refused (a challenge came from a page whose hostname the widget does not list).
widget.disabled_reason string or null Why our team turned the widget off, or null when it is not turned off.
widget.appearance Appearance The theme, size and language the widget uses when the page sets none.
widget.secret_prefix string The start of the secret key, to tell keys apart. The rest is never shown again.
widget.secret_rotated_at string or null
widget.previous_secret_expires_at string or null When the secret key you replaced stops working, while a rotation's grace period is running.
widget.limits Limits What your plan allows: {"hostnames": 10} is the most hostnames one widget lists.
widget.embed Embed
secret string The secret key. It is shown once, so save it now.

Tell Wicket what a passed check turned out to be

Section titled Tell Wicket what a passed check turned out to be

POST /api/v1/wicket/feedback

Tell Wicket what a passed check turned out to be.

When you learn that an account or an order your form made was a bot, or was a person Wicket doubted, post the check's event (from metadata.event in the siteverify answer), with your widget's secret key and a label of bot or human. Our team and the model that scores checks learn from your report. The answer is 202 and the report starts as confirmed.

application/json (required)

Field Type Required Description
secret string yes The widget's secret key, which starts with wks_.
event string yes The check's id, from metadata.event in the siteverify answer. 32 hex characters.
label string yes What the visitor turned out to be: "bot" or "human".
note string or null no A short note for our team, at most 500 characters.
Status Meaning
202 Success.
403 The secret key is not a widget's. The answer names the error invalid_secret.
422 The event is not a check of this widget, or the label is not bot or human.
429 The widget used its budget of calls for the minute.

Fields of a 202 response:

Field Type Description
status string Always "received".

Check a token the widget put in your form

Section titled Check a token the widget put in your form

POST /api/v1/wicket/siteverify

Check a token the widget put in your form.

Post the widget's secret key and the token (response) from your server, form-encoded, as multipart form data or as JSON, as you would to Cloudflare Turnstile. The answer is always HTTP 200 with success true or false and an error-codes list, except when the widget has used its budget of calls for the minute (6000 by default), which is HTTP 429 with the code rate-limited.

A token passes once: a second call with the same token answers timeout-or-duplicate, unless you send the same idempotency_key, which returns the first answer again. A token is also timeout-or-duplicate when it is more than 300 seconds old. On success, check that hostname is your own and, if you set one on the widget, that action is the one you expect. metadata.event is the check's id, for the feedback call.

The test secret keys wks_test_pass, wks_test_fail and wks_test_spent answer a fixed result for any token and count nowhere.

application/x-www-form-urlencoded (required)

Field Type Required Description
secret string yes The widget's secret key, which starts with wks_. Keep it on your server.
response string yes The token the widget put in your form, from the field named wicket-response. At most 2048 characters.
remoteip string or null no The visitor's IP address as your server sees it. Wicket notes whether it comes from the same network that solved the check. It never changes the answer.
idempotency_key string or null no A value you choose for this verification, such as a UUID. If you send the same token again with the same key, you get the first answer again instead of timeout-or-duplicate. Use it when a network error makes you repeat a call.
Status Meaning
200 Success.
429 The widget used its budget of siteverify calls for the minute (error code rate-limited).

Fields of a 200 response:

Field Type Description
success boolean True when the token is valid for this widget and had not been used.
challenge_ts string or null When the visitor passed the check, in UTC.
hostname string or null The hostname of the page that showed the widget. Compare it with your own.
error-codes array of string Why the call failed, empty when it succeeded. One or more of: missing-input-secret, invalid-input-secret, missing-input-response, invalid-input-response, bad-request, timeout-or-duplicate, internal-error and rate-limited.
action string or null The action the page set on the widget, or an empty string.
cdata string or null The cdata the page set on the widget, or an empty string.
metadata SiteverifyMetadata or null More about the check, on success.
metadata.interactive boolean True when the visitor ticked the checkbox to pass.
metadata.event string The id of this check, 32 hex characters. Store it with the record the form made (an account, an order) to report later, with the feedback call, whether that record was a person or a bot.