Skip to main content
Your auth provider can ask NoResponse about each account creation and each login before it lets the user in. NoResponse hosts the endpoint that the provider calls. It scores the event and answers allow or deny, and the provider enforces the answer. You run no server for this, and your application code does not change. Each event goes through these steps:
  1. A user creates an account or logs in through Auth0 or WorkOS.
  2. The provider’s Action calls POST https://api.noresponse.org/hooks/{integration_id}.
  3. NoResponse scores the event and answers allow or deny.
  4. The provider creates the user or lets them in, or it refuses with an error message.
NoResponse supports two auth providers:
  • Auth0: NoResponse publishes two Actions. One is for the Pre User Registration trigger and one is for the Login trigger. You paste them into your Auth0 tenant and give them two secrets.
  • WorkOS: the AuthKit user registration and authentication Actions. You point both at the hosted URL. There is no code to install.
The hosted endpoint denies only when the account’s decision, account.risk.decision, is block. No account’s decision is block until you set a block threshold. Until then NoResponse scores and allows every event. You can install the integration, check the scores of your users’ logins, and then turn blocking on.

How the endpoint decides

Each call creates an assessment from what the provider sends. That is the email, username, phone number, name and IP address. At login it also includes the provider’s session facts. Then these rules apply:
  • It waits for the full score. The endpoint waits for the assessment to complete, then decides on the latest version. It waits at most 2.5 seconds from the request’s arrival for WorkOS and 4.5 seconds for Auth0. Sources that are still running at that point keep running. Later versions reach your webhooks as usual.
  • It denies only on block. The answer is deny when the account’s decision is block. That happens once the score reaches your block threshold. In every other case the answer is allow. The other decisions, the band and the reason codes do not change the answer on their own.
  • It fails open. Any failure on the NoResponse side answers allow. Examples are a body that NoResponse cannot assess, an unavailable service, or no complete score within the time limit. A request without valid authentication answers 401, and an unknown integration id answers 404. Your provider then applies its own failure setting. When you follow the steps on this page, that setting lets the user through.
  • A retry gets the same answer. The provider can retry the same event, with the same WorkOS Action id or the same Auth0 transaction id. For 24 hours, the retry gets the same assessment and decision.
  • Both hook points are on by default. pre_registration runs before the user exists, and post_login runs after a successful login. An integration can list only one. NoResponse allows an event at a hook point that the integration does not list, and creates no assessment. See Choose the hook points.
At login the assessment uses flow login and your provider’s user id as its account_id. The login then shows in that account’s history, and the account’s current risk carries into the decision. At account creation the assessment uses flow account_creation. There is no user yet, so its account_id is pre: and then its own assessment id.

Set your block threshold

The account’s decision is block when you set a block threshold and the score is at or above it. The threshold is off by default. While it is off, the endpoint denies nothing. To turn blocking on, email info@noresponse.org with the score to block from. It can be any score from your review threshold to 100. The review threshold is the score from which the decision is review. It is 75, unless we agreed another value with you. A block threshold of 90 denies only the riskiest account creations. A threshold of 75 denies everything we would send to review. Ask us the same way to change it or turn it off. When you set the threshold, every assessment carries it. This is true for an assessment from a hook and for one from POST /v1/assessments. If you also call the API from your own backend, act on account.risk.decision there and refuse on block the same way.

Before you start

You need an API key with the integrations scope, and admin access to your Auth0 tenant or your WorkOS environment. Every key that you get when you create a workspace has the integrations scope, as in Get a key.
The key creates and manages integrations, and it stays on your side. The provider holds only the integration’s own secret. The SDK samples read the key from NORESPONSE_API_KEY, as in the Quickstart:
  • In TypeScript, nr is new NoResponse().
  • In Python, client is NoResponse().
  • In Go, client is noresponse.NewClient(os.Getenv("NORESPONSE_API_KEY")).
  • The cURL samples send the key as a bearer token.
An integration belongs to one Auth0 tenant or one WorkOS environment. Create one integration for each tenant or environment that you connect. For example, create one for your development tenant and one for production. Your platform can hold up to 10 integrations.

Install the integration

The two Actions call your integration’s URL with a shared secret and wait up to 5 seconds. They block the account creation or login only when NoResponse answers deny. They run on Auth0’s Node 22 runtime with no npm packages. Auth0 includes Actions on every plan. The Free plan allows five Actions and Forms in total.Auth0 runs the Pre User Registration trigger only for Database and Passwordless connections. A user who creates an account through a social or enterprise connection meets the Login trigger at their first login. Install the login Action as well to cover them.
1

Create the integration

Create an integration with "platform": "auth0". NoResponse generates the shared secret and returns it in secret, once. Keep the answer open until both Actions hold it.
TypeScript
The answer is 201:
Response
url is the value for NORESPONSE_HOOK_URL, and secret is the value for NORESPONSE_HOOK_SECRET. The secret starts with nri_, and NoResponse does not show it again. If you lose it, rotate it.
2

Install the Actions

Install each Action in the Auth0 dashboard. To install both at once, use the Management API script.
pre-user-registration.js
post-login.js
The same files, with the deploy script, are in /integrations/auth0/actions.json on this site. The Management API script section downloads them.Do these steps for each of the two files:
  1. In the Auth0 dashboard, open Actions, then Library, then Create Action and Build from scratch.
  2. Give it a name, for example “NoResponse account creation risk check” or “NoResponse login risk check”.
  3. Choose the trigger from the table above and the Node 22 runtime. Then select Create.
  4. Replace the editor’s code with the whole file.
  5. Open Secrets (the key icon) and add these values:
    • NORESPONSE_HOOK_URL: the integration’s url.
    • NORESPONSE_HOOK_SECRET: the integration’s secret.
    • NORESPONSE_TIMEOUT_MS (optional): how long the Action waits for NoResponse, in milliseconds. The default is 5000, and the largest value it accepts is 8000. NoResponse answers within 4.5 seconds, so a value below 4500 lets some events through unscored.
  6. Select Deploy.
  7. Open Actions, then Triggers. Open pre-user-registration for the account creation Action, or post-login for the login Action.
  8. Drag the Action from Custom into the flow between Start and Complete. Then select Apply.
A refused account creation sees “We could not create your account. Please contact support.” A refused login returns access_denied to your application with the description “Sign-in blocked. Please contact support.” To use your own words, change USER_MESSAGE in pre-user-registration.js or DENY_REASON in post-login.js before you deploy.Each Action writes one log line, and only in two cases: when it denies, or when it allows without a decision. The line holds the hook point, the decision, and the assessment id or the reason. No secret, email address or IP address goes in the log.
3

Test it

  1. In the Action editor, select Test (the play icon) and Run. Auth0’s sample event has no real user, so NoResponse answers allow.
  2. Read the Action’s log in the test output. A correct setup writes nothing.
  3. A line such as noresponse post_login: allowed without a decision (status 401) means that the Action could not get a decision. The table below gives the cause.
  4. Create an account with a new test user through your application, then log in with it. Both pass while your block threshold is off.
  5. Read the login’s assessment. Use a key with the history scope to query the account’s history. Use the Auth0 user id, such as auth0|64abc, as the account_id. See Get and query assessments.
A deny writes noresponse pre_registration: deny, assessment asm_..., or the same line with post_login. Use the id to find the assessment.

Install with the Management API

scripts/deploy-to-tenant.mjs does every Auth0 dashboard step above in one command. It does these things:
  1. It creates or updates both Actions with their secrets.
  2. It waits for Auth0 to build them.
  3. It runs Auth0’s Action test on each.
  4. Only when the test passes, it deploys the Action and adds it to its trigger. It keeps any Actions that are already there.
When you run it again, it updates the Actions in place. It prints no secrets, and it needs Node 22 with no npm packages. Download the three files into the layout the script expects. actions.json holds the exact contents of each file under its path. The second command writes them out.
Download the Auth0 files
This is the script:
deploy-to-tenant.mjs
In Auth0, create a Machine to Machine application. Authorise it for the Auth0 Management API with the read:actions, create:actions and update:actions scopes. Then run this command with your own values:
Deploy the Actions
--skip-test=post-login skips Auth0’s test run for the login Action. Auth0’s Action test endpoint fails for every Login Action with Cannot read properties of undefined (reading 'ip'). Test that Action in the Action editor instead, as in the Test it step. The script exits 0 when every step succeeded. It exits 2 when a required value is missing, and in that case it called nothing.

What the Auth0 Actions send and receive

Each call is POST <url> with Authorization: Bearer <secret> and a JSON body built from the Auth0 event. The Action leaves out the fields that Auth0 does not supply. At account creation, Auth0 has no user id, verification flags, creation time or session yet. The account creation Action sends only the email, username, phone number, name, request and connection.
Request body
NoResponse answers 200 with the decision. A deny carries the assessment that it used:
Response
An allow that NoResponse could not score is { "decision": "allow" } with nothing else. The Action blocks only on "decision": "deny". It treats any other answer, status or failure as allow.

Choose the hook points

Both hook points are on unless you list fewer. To score account creation only, create the integration with hook_points:
TypeScript
NoResponse answers allow to an event at a hook point that the integration does not list, and creates no assessment. You choose the hook points once, when you create the integration. To change them, do these steps:
  1. Create a new integration with the list that you want.
  2. Move the provider to its URL. For Auth0, also move the provider to its secret.
  3. Delete the old integration.
You can also turn a hook point off at the provider. Take the Auth0 Action out of its trigger, or turn off Enable on the WorkOS Action. The provider then never calls NoResponse for that event.

Manage integrations

Every call below needs a key with the integrations scope. GET /v1/integrations lists your integrations, oldest first, without secrets. The interactive reference has every field.

Rotate a secret

POST /v1/integrations/{integration_id}/rotate replaces the secret. NoResponse still accepts the replaced secret for 24 hours, until previous_secret_expires_at. You can switch the provider over without a refused call.
  • Auth0: send {}. The answer holds the new secret, shown once. Put it in NORESPONSE_HOOK_SECRET on both Actions and deploy them within 24 hours.
  • WorkOS: regenerate the signing secret in the WorkOS dashboard, then send it as signing_secret immediately. WorkOS signs with the new secret from the moment you regenerate it. NoResponse refuses those calls until it has the new secret.
Rotation is not idempotent. A retry after a lost answer rotates again. The secret that was in force before the first call then stops working at once.
TypeScript
For WorkOS, pass the new secret. It is signingSecret in TypeScript, signing_secret in Python and cURL, and SigningSecret in Go.

Delete an integration

First take the Actions out of the provider. Take the Auth0 Actions out of their triggers, or turn off Enable on both WorkOS Actions. Then delete the integration with DELETE /v1/integrations/{integration_id}, which answers 204. From then on its URL answers 404, and the provider applies its own failure setting.
Delete an integration
Creating an integration is not idempotent either. A retry after a lost answer creates a second integration, which you can list and delete. When you already have 10 integrations, a new one answers 409 too_many_integrations.

After the hook answers

The hook decides at its time limit. A source that answers later can still move the score. That later version reaches your webhooks like any other assessment.updated. A later version can move the decision to block for an account that the hook already let in. Act on it from your webhook receiver, for example by suspending the account. Turn an assessment into a decision has the rules to apply.