curl --request POST \
--url 'https://api.noresponse.org/v1/integrations/int_01JA2Z8K6Q4V7W9XBCDEFGHJKM/rotate' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.integrations.rotate({
integrationId: "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
body: {},
});
console.log(result);
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.integrations.rotate(integration_id="int_01JA2Z8K6Q4V7W9XBCDEFGHJKM", signing_secret="wos_action_secret_Z9cD1eF5gH0jL4sP")
# Handle response
print(res)
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v5"
"github.com/noresponsehq/go/v5/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Integrations.Rotate(ctx, "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM", components.IntegrationRotationRequest{})
if err != nil {
log.Fatal(err)
}
if res != nil {
// handle response
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.RotateIntegrationSecretResponse;
import org.noresponse.models.shared.IntegrationRotationRequest;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
RotateIntegrationSecretResponse res = sdk.integrations().rotate()
.integrationId("int_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
.body(IntegrationRotationRequest.builder()
.build())
.call();
if (res.integration().isPresent()) {
System.out.println(res.integration().get());
}
}
}
using NoResponse;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
var res = await sdk.Integrations.RotateAsync(
integrationId: "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
body: new IntegrationRotationRequest() {}
);
// handle response
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$body = new Shared\IntegrationRotationRequest();
$response = $sdk->integrations->rotate(
integrationId: 'int_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
body: $body
);
if ($response->integration !== null) {
// handle response
}
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
res = s.integrations.rotate(integration_id: 'int_01JA2Z8K6Q4V7W9XBCDEFGHJKM', body: Models::Shared::IntegrationRotationRequest.new)
unless res.nil?
# handle response
end
{
"integration_id": "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"platform": "auth0",
"hook_points": [
"pre_registration",
"post_login"
],
"url": "https://api.noresponse.org/hooks/int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"secret": "nri_Z9cD1eF5gH0jL4sP9uV2wX7yAk3Yx8pQ2mN7vR4tW6A",
"created_at": "2026-10-14T09:00:00.000Z",
"rotated_at": "2026-10-15T09:00:00.000Z",
"previous_secret_expires_at": "2026-10-16T09:00:00.000Z"
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}Rotate an integration's secret
For Auth0, send {}: the answer’s secret is the new shared secret, shown once. For WorkOS, regenerate the Actions secret in the WorkOS dashboard and send it as signing_secret.
The old secret is still accepted for 24 hours (previous_secret_expires_at), so you can switch the provider over without a refused call. Rotation is not idempotent. Requires the integrations scope.
curl --request POST \
--url 'https://api.noresponse.org/v1/integrations/int_01JA2Z8K6Q4V7W9XBCDEFGHJKM/rotate' \
--header "Authorization: Bearer $NORESPONSE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{}'
import { NoResponse } from "@noresponse/node";
const noResponse = new NoResponse({
apiKey: process.env["NORESPONSE_API_KEY"] ?? "",
});
async function run() {
const result = await noResponse.integrations.rotate({
integrationId: "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
body: {},
});
console.log(result);
}
run();
from noresponse import NoResponse
import os
with NoResponse(
api_key=os.getenv("NORESPONSE_API_KEY", ""),
) as no_response:
res = no_response.integrations.rotate(integration_id="int_01JA2Z8K6Q4V7W9XBCDEFGHJKM", signing_secret="wos_action_secret_Z9cD1eF5gH0jL4sP")
# Handle response
print(res)
package main
import(
"context"
"os"
noresponse "github.com/noresponsehq/go/v5"
"github.com/noresponsehq/go/v5/models/components"
"log"
)
func main() {
ctx := context.Background()
s := noresponse.New(
noresponse.WithSecurity(os.Getenv("NORESPONSE_API_KEY")),
)
res, err := s.Integrations.Rotate(ctx, "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM", components.IntegrationRotationRequest{})
if err != nil {
log.Fatal(err)
}
if res != nil {
// handle response
}
}
package hello.world;
import java.lang.Exception;
import org.noresponse.NoResponse;
import org.noresponse.models.errors.AuthenticationException;
import org.noresponse.models.errors.BadRequestException;
import org.noresponse.models.errors.ConflictException;
import org.noresponse.models.errors.NotFoundException;
import org.noresponse.models.errors.PermissionDeniedException;
import org.noresponse.models.errors.RateLimitException;
import org.noresponse.models.operations.RotateIntegrationSecretResponse;
import org.noresponse.models.shared.IntegrationRotationRequest;
public class Application {
public static void main(String[] args) throws Exception {
NoResponse sdk = NoResponse.builder()
.apiKey(System.getenv().getOrDefault("NORESPONSE_API_KEY", ""))
.build();
RotateIntegrationSecretResponse res = sdk.integrations().rotate()
.integrationId("int_01JA2Z8K6Q4V7W9XBCDEFGHJKM")
.body(IntegrationRotationRequest.builder()
.build())
.call();
if (res.integration().isPresent()) {
System.out.println(res.integration().get());
}
}
}
using NoResponse;
using NoResponse.Models.Shared;
using System;
var sdk = new NoResponseClient(apiKey: Environment.GetEnvironmentVariable("NORESPONSE_API_KEY"));
var res = await sdk.Integrations.RotateAsync(
integrationId: "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
body: new IntegrationRotationRequest() {}
);
// handle response
<?php
declare(strict_types=1);
require 'vendor/autoload.php';
use NoResponse;
use NoResponse\Models\Shared;
$sdk = NoResponse\NoResponseClient::builder()
->setSecurity(
getenv('NORESPONSE_API_KEY') ?: ''
)
->build();
$body = new Shared\IntegrationRotationRequest();
$response = $sdk->integrations->rotate(
integrationId: 'int_01JA2Z8K6Q4V7W9XBCDEFGHJKM',
body: $body
);
if ($response->integration !== null) {
// handle response
}
require 'noresponse'
Models = ::NoResponse::Models
s = ::NoResponse::NoResponseClient.new(
api_key: ENV.fetch('NORESPONSE_API_KEY', '')
)
res = s.integrations.rotate(integration_id: 'int_01JA2Z8K6Q4V7W9XBCDEFGHJKM', body: Models::Shared::IntegrationRotationRequest.new)
unless res.nil?
# handle response
end
{
"integration_id": "int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"platform": "auth0",
"hook_points": [
"pre_registration",
"post_login"
],
"url": "https://api.noresponse.org/hooks/int_01JA2Z8K6Q4V7W9XBCDEFGHJKM",
"secret": "nri_Z9cD1eF5gH0jL4sP9uV2wX7yAk3Yx8pQ2mN7vR4tW6A",
"created_at": "2026-10-14T09:00:00.000Z",
"rotated_at": "2026-10-15T09:00:00.000Z",
"previous_secret_expires_at": "2026-10-16T09:00:00.000Z"
}{
"type": "<string>",
"title": "<string>",
"status": 400,
"detail": "<string>",
"code": "invalid_request",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 401,
"detail": "<string>",
"code": "unauthorized",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/workspace-forbidden",
"title": "Forbidden",
"status": 403,
"detail": "The API key does not carry a scope this operation accepts.",
"code": "workspace_forbidden",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 404,
"detail": "<string>",
"code": "not_found",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 413,
"detail": "<string>",
"code": "payload_too_large",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 415,
"detail": "<string>",
"code": "unsupported_media_type",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}{
"type": "https://docs.noresponse.org/problems/rate-limited",
"title": "Rate limited",
"status": 429,
"detail": "The tenant's assessment rate is exhausted; retry after the Retry-After interval.",
"code": "rate_limited",
"request_id": "0123456789abcdef0123456789abcdef"
}{
"type": "<string>",
"title": "<string>",
"status": 503,
"detail": "<string>",
"code": "service_unavailable",
"request_id": "<string>",
"instance": "<string>",
"invalid_params": [
{
"field": "<string>",
"reason": "<string>",
"example": "<string>"
}
]
}Authorizations
Your API key, sent as Authorization: Bearer <key>. A key is nrk_live_ or nrk_test_, a 26-character key id, _ and a 43-character secret. A key sees only its own environment's data.
Each key has one or more scopes: assess creates and reads assessments, records outcomes and reports key usage; history reads assessments, an account's current risk and an account's history, and erases an account; detailed adds the detailed view; webhooks registers, tests, rotates and deletes webhook endpoints; integrations registers and manages hosted provider integrations. A missing, unknown, revoked or expired key answers 401. A valid key without the scope an operation needs answers 403.
Path Parameters
Path segment, matched case-sensitively. A value that does not match the integration_id shape, or another workspace's id, answers 404. Opaque, server-assigned integration id: int_ and a 26-character Crockford base32 ULID. Another workspace's integration id answers 404.
^int_[0-7][0-9A-HJKMNP-TV-Z]{25}$Body
POST /v1/integrations/{integration_id}/rotate body. For an Auth0 integration send {}: NoResponse generates a new shared secret and returns it once. For a WorkOS integration send the new signing_secret after regenerating it in the WorkOS dashboard. Either way the previous secret is still accepted for 24 hours, so the provider can be switched over without a refused call.
The WorkOS Actions signing secret, as the WorkOS dashboard shows it: 16 to 256 printable ASCII characters with no spaces. It is stored sealed and is not returned.
16 - 256^[!-~]{16,256}$Response
The integration with its new secret. For Auth0, secret is the new shared secret, shown once. previous_secret_expires_at says until when the replaced secret is still accepted.
A hosted provider integration. Point the provider at url: a WorkOS user registration or authentication Action, or the NoResponse Auth0 Action, which sends secret as a bearer token. The answer allows or denies the event: deny only when the assessment's risk.block is true, and allow on every failure, so a fault on the NoResponse side lets the user through. secret is present only in the answers of POST /v1/integrations and POST /v1/integrations/{integration_id}/rotate for an Auth0 integration, and is not returned again.
Opaque, server-assigned integration id: int_ and a 26-character Crockford base32 ULID. Another workspace's integration id answers 404.
^int_[0-7][0-9A-HJKMNP-TV-Z]{25}$The authentication provider that calls the endpoint.
workos, auth0 Each hook point at most once.
1 - 2 elementspre_registration runs before the user exists; post_login runs after a successful sign-in.
pre_registration, post_login The hosted endpoint, https://api.noresponse.org/hooks/{integration_id} in production.
256^https://[A-Za-z0-9.-]+(?::[0-9]{1,5})?/hooks/int_[0-7][0-9A-HJKMNP-TV-Z]{25}$Auth0 only, and only when it is created or rotated: the shared secret the Auth0 Action sends as Authorization: Bearer . nri_ and 43 unpadded base64url characters (32 random bytes). Store it as an Auth0 Action secret.
^nri_[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$When the secret was last rotated; absent until the first rotation.
After a rotation, when the replaced secret stops being accepted; absent when no replaced secret is still accepted.