Reactors
For an overview of Reactors and when to use them, see What are Reactors?.
Runtime Options
Reactors run in Basis Theory's Runtime environment and support the next images:
| Runtime | Description | Provisioning |
|---|---|---|
| node-bt | Default runtime with curated dependencies. No runtime object needed. | Synchronous |
| node22 | Modern Node.js 22 that offers dependency customization. | Asynchronous |
Create Reactor
Create a new Reactor for the Tenant.
node22 provisioning is asynchronous. Check valid states for execution.
Permissions
reactor:create
Request
- node-bt
- node22
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
javascript='module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};'
curl "https://api.basistheory.com/reactors" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"name": "My Reactor",
"code": '"$(echo $javascript | jq -Rsa .)"',
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"application": {
"id": "45c124e7-6ab2-4899-b4d9-1388b0ba9d04"
}
}'
await client.reactors.create({
name: "My Reactor",
code: `
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
application: {
id: applicationId,
}
})
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.create({
name: "My Reactor",
code: `
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
application: {
id: "45c124e7-6ab2-4899-b4d9-1388b0ba9d04",
},
});
await client.Reactors.CreateAsync(new CreateReactorRequest
{
Name = "My Reactor",
Code = @"
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: ""bar""
}
};
};",
Configuration = new Dictionary<string, string?>
{
{ "SERVICE_API_KEY", "key_abcd1234" }
},
Application = new Application
{
Id = applicationId
}
});
new ReactorsClient(ClientOptions.builder().build()).create(CreateReactorRequest.builder()
.name("My Reactor")
.code("...")
.configuration(new HashMap<>())
.application(Application.builder().id("applicationId").build())
.build());
client.reactors.create(
name='My Reactor',
code="""module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};""",
configuration={
"SERVICE_API_KEY": "key_abcd1234"
},
application={
"id": application_id
}
)
code := `module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};`
reactor, err := client.Reactors.Create(ctx, &basistheory.CreateReactorRequest{
Name: "My Reactor",
Code: code,
Configuration: map[string]*string{
"SERVICE_API_KEY": func(s string) *string { return &s }("key_abcd1234"),
},
Application: &basistheory.Application{
ID: applicationID,
},
})
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
javascript='module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};'
curl "https://api.basistheory.com/reactors" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/json" \
-X "POST" \
-d '{
"name": "My Reactor",
"code": '"$(echo $javascript | jq -Rsa .)"',
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 10,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
}'
await client.reactors.create({
name: "My Reactor",
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
runtime: {
image: "node22",
dependencies: {
maskdata: "1.3.2",
},
resolutions: {
minimist: "1.2.8",
},
timeout: 10,
resources: "standard",
warmConcurrency: 0,
permissions: ["token:reveal", "token:create"],
}
})
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.create({
name: "My Reactor",
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
runtime: {
image: "node22",
dependencies: {
maskdata: "1.3.2",
},
resolutions: {
minimist: "1.2.8",
},
timeout: 10,
resources: "standard",
warm_concurrency: 0,
permissions: ["token:reveal", "token:create"],
},
});
await client.Reactors.CreateAsync(new CreateReactorRequest
{
Name = "My Reactor",
Code = @"
module.exports = async function (event) {
const MaskData = require('maskdata');
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: '*',
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};",
Configuration = new Dictionary<string, string?>
{
{ "SERVICE_API_KEY", "key_abcd1234" }
},
Runtime = new Runtime
{
Image = "node22",
Dependencies = new Dictionary<string, string?>
{
{ "maskdata", "1.3.2" }
},
Resolutions = new Dictionary<string, string?>
{
{ "minimist", "1.2.8" }
},
Timeout = 10,
Resources = "standard",
WarmConcurrency = 0,
Permissions = new List<string> { "token:reveal", "token:create" }
}
});
new ReactorsClient(ClientOptions.builder().build()).create(CreateReactorRequest.builder()
.name("My Reactor")
.code("...")
.configuration(Map.of("SERVICE_API_KEY", "key_abcd1234"))
.runtime(Runtime.builder()
.image("node22")
.dependencies(Map.of("maskdata", "1.3.2"))
.resolutions(Map.of("minimist", "1.2.8"))
.timeout(10)
.resources("standard")
.warmConcurrency(0)
.permissions(List.of("token:reveal", "token:create"))
.build())
.build());
client.reactors.create(
name='My Reactor',
code="""module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};""",
configuration={
"SERVICE_API_KEY": "key_abcd1234"
},
runtime={
"image": "node22",
"dependencies": {
"maskdata": "1.3.2"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 10,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
)
code := `module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
masked_card: masked_card
},
statusCode: 200
}
};
};`
reactor, err := client.Reactors.Create(ctx, &basistheory.CreateReactorRequest{
Name: "My Reactor",
Code: code,
Configuration: map[string]*string{
"SERVICE_API_KEY": basistheory.String("key_abcd1234"),
},
Runtime: &basistheory.Runtime{
Image: basistheory.String("node22"),
Dependencies: map[string]*string{
"maskdata": basistheory.String("1.3.2"),
},
Resolutions: map[string]*string{
"minimist": basistheory.String("1.2.8"),
},
Timeout: basistheory.Int(10),
Resources: basistheory.String("standard"),
WarmConcurrency: basistheory.Int(0),
Permissions: []string{"token:reveal", "token:create"},
},
})
Request Parameters
| Attribute | Required | Type | Runtime | Description |
|---|---|---|---|---|
name | true | string | All | The name of the reactor. Has a maximum length of 200 |
code | true | string | All | Reactor code which will be executed when the Reactor is processed |
configuration | false | map<string, string> | All | A string key and string value map of predefined configuration names and values accessible from the Reactor code |
runtime | false | Runtime Object | All | Runtime configuration for the reactor. |
application.id | false | uuid | node-bt | This Application's API key is injected into a pre-configured BasisTheory JS SDK instance passed into the Reactor's runtime. Must be a public or private Application Type. |
Response
Returns a Reactor if the Reactor was created. Returns an error if there were validation errors, or the Reactor failed to create.
- node-bt
- node22
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"code": "
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: 'bar',
}
};
};
",
"application": {...},
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"created_by": "3ce0dceb-fd0b-4471-8006-c51243c9ef7a",
"created_at": "2020-09-15T15:53:00+00:00"
}
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"state": "creating",
"requested": {
"reactor": {
"code": "module.exports = async function (event) { ... }",
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 10,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
}
},
"created_by": "3ce0dceb-fd0b-4471-8006-c51243c9ef7a",
"created_at": "2020-09-15T15:53:00+00:00"
}
List Reactors
Get a list of reactors for the Tenant.
Permissions
reactor:read
Request
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
curl "https://api.basistheory.com/reactors" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>"
const response = await client.reactors.list();
for await (const item of response) {
console.log(item);
}
// Or you can manually iterate page-by-page
const page = await client.reactors.list();
while (page.hasNextPage()) {
page = page.getNextPage();
}
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactors = await bt.reactors.list();
await client.Reactors.ListAsync(new ReactorsListRequest());
new ReactorsClient(ClientOptions.builder().build()).list();
response = client.reactors.list()
for item in response:
yield item
# alternatively, you can paginate page-by-page
for page in response.iter_pages():
yield page
// List all reactors
reactors, err := client.Reactors.List(ctx, &basistheory.ReactorsListRequest{})
Query Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
id | false | array | [] | An optional list of Reactor ID's to filter the list of reactors by |
name | false | string | null | Wildcard search of reactors by name |
Response
Returns a paginated object with the data property containing an array of reactors. Providing any query parameters will filter the results. Returns an error if reactors could not be retrieved.
{
"pagination": {...}
"data": [
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"code": "
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: 'bar',
}
};
};
",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"created_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"created_at": "2020-09-15T15:53:00+00:00",
"modified_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"modified_at": "2021-03-01T08:23:14+00:00"
},
{...},
{...}
]
}
Get a Reactor
Get a Reactor by ID in the Tenant.
Permissions
reactor:read
Request
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
curl "https://api.basistheory.com/reactors/5b493235-6917-4307-906a-2cd6f1a90b13" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>"
await client.reactors.get("id");
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.retrieve(
"5b493235-6917-4307-906a-2cd6f1a90b13"
);
await client.Reactors.GetAsync("id");
new ReactorsClient(ClientOptions.builder().build()).get("id");
client.reactors.get(
id="id",
)
reactor, err := client.Reactors.Get(ctx, "id")
URI Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
id | true | uuid | null | The ID of the reactor |
Response
Returns a Reactor with the id provided. Returns an error if the Reactor could not be retrieved.
- node-bt
- node22
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"code": "
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: 'bar',
}
};
};
",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"created_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"created_at": "2020-09-15T15:53:00+00:00",
"modified_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"modified_at": "2021-03-01T08:23:14+00:00"
}
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"state": "active",
"code": "module.exports = async function (event) { ... }",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2",
"stripe": "18.4.0"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 10,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
},
"created_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"created_at": "2020-09-15T15:53:00+00:00",
"modified_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"modified_at": "2021-03-01T08:23:14+00:00"
}
Update Reactor
Update a Reactor by ID in the Tenant.
node22 updates are asynchronous. Check valid states where node22 can be updated.
Permissions
reactor:update
Request
- node-bt
- node22
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
javascript='module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};'
curl "https://api.basistheory.com/reactors/5b493235-6917-4307-906a-2cd6f1a90b13" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/json" \
-X "PUT" \
-d '{
"name": "My Reactor",
"code": '"$(echo $javascript | jq -Rsa .)"',
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"application": {
"id": "45c124e7-6ab2-4899-b4d9-1388b0ba9d04"
}
}'
await client.reactors.update(
reactorId,
{
name: "My Reactor",
code: `
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
application: {
id: applicationId,
}
}
);
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.update(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
name: "My Reactor",
code: `
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
application: {
id: "45c124e7-6ab2-4899-b4d9-1388b0ba9d04",
},
}
);
await client.Reactors.UpdateAsync(
reactorId,
new UpdateReactorRequest
{
Name = "My Reactor",
Code = @"
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: ""bar""
}
};
};",
Configuration = new Dictionary<string, string?>
{
{ "SERVICE_API_KEY", "key_abcd1234" }
},
Application = new Application
{
Id = applicationId
}
}
);
new ReactorsClient(ClientOptions.builder().build()).update("id", UpdateReactorRequest.builder()
.name("My Reactor")
.code("...")
.configuration(new HashMap<>())
.application(Application.builder().id("applicationId").build())
.build());
client.reactors.update(
id = reactor_id,
name='My Reactor',
code="""module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};""",
configuration={
"SERVICE_API_KEY": "key_abcd1234"
},
application={
"id": application_id
}
)
code := `module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: "bar"
}
};
};`
reactor, err := client.Reactors.Update(ctx, reactorId, &basistheory.UpdateReactorRequest{
Name: "My Reactor",
Code: code,
Configuration: map[string]*string{
"SERVICE_API_KEY": func(s string) *string { return &s }("key_abcd1234"),
},
})
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
javascript='module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Updated response",
masked_card: masked_card
},
statusCode: 200
}
};
};'
curl "https://api.basistheory.com/reactors/5b493235-6917-4307-906a-2cd6f1a90b13" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/json" \
-X "PUT" \
-d '{
"name": "My Updated Reactor",
"code": '"$(echo $javascript | jq -Rsa .)"',
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2",
"stripe": "18.4.0",
"lodash": "4.17.21"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 15,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
}'
await client.reactors.update(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
name: "My Updated Reactor",
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Updated response",
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
runtime: {
image: "node22",
dependencies: {
maskdata: "1.3.2",
stripe: "18.4.0",
lodash: "4.17.21",
},
resolutions: {
minimist: "1.2.8",
},
timeout: 15,
resources: "standard",
warmConcurrency: 0,
permissions: ["token:reveal", "token:create"],
}
}
);
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.update(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
name: "My Updated Reactor",
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Updated response",
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
configuration: {
SERVICE_API_KEY: "key_abcd1234",
},
runtime: {
image: "node22",
dependencies: {
maskdata: "1.3.2",
stripe: "18.4.0",
lodash: "4.17.21",
},
resolutions: {
minimist: "1.2.8",
},
timeout: 15,
resources: "standard",
warm_concurrency: 0,
permissions: ["token:reveal", "token:create"],
},
}
);
await client.Reactors.UpdateAsync(
"5b493235-6917-4307-906a-2cd6f1a90b13",
new UpdateReactorRequest
{
Name = "My Updated Reactor",
Code = @"
module.exports = async function (event) {
const MaskData = require('maskdata');
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: '*',
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: 'Updated response',
masked_card: masked_card
},
statusCode: 200
}
};
};",
Configuration = new Dictionary<string, string?>
{
{ "SERVICE_API_KEY", "key_abcd1234" }
},
Runtime = new Runtime
{
Image = "node22",
Dependencies = new Dictionary<string, string?>
{
{ "maskdata", "1.3.2" },
{ "stripe", "18.4.0" },
{ "lodash", "4.17.21" }
},
Resolutions = new Dictionary<string, string?>
{
{ "minimist", "1.2.8" }
},
Timeout = 15,
Resources = "standard",
WarmConcurrency = 0,
Permissions = new List<string> { "token:reveal", "token:create" }
}
}
);
new ReactorsClient(ClientOptions.builder().build()).update("5b493235-6917-4307-906a-2cd6f1a90b13", UpdateReactorRequest.builder()
.name("My Updated Reactor")
.code("...")
.configuration(Map.of("SERVICE_API_KEY", "key_abcd1234"))
.runtime(Runtime.builder()
.image("node22")
.dependencies(Map.of("maskdata", "1.3.2", "stripe", "18.4.0", "lodash", "4.17.21"))
.resolutions(Map.of("minimist", "1.2.8"))
.timeout(15)
.resources("standard")
.warmConcurrency(0)
.permissions(List.of("token:reveal", "token:create"))
.build())
.build());
client.reactors.update(
id="5b493235-6917-4307-906a-2cd6f1a90b13",
name='My Updated Reactor',
code="""module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Updated response",
masked_card: masked_card
},
statusCode: 200
}
};
};""",
configuration={
"SERVICE_API_KEY": "key_abcd1234"
},
runtime={
"image": "node22",
"dependencies": {
"maskdata": "1.3.2",
"stripe": "18.4.0",
"lodash": "4.17.21"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 15,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
)
code := `module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Updated response",
masked_card: masked_card
},
statusCode: 200
}
};
};`
reactor, err := client.Reactors.Update(ctx, "5b493235-6917-4307-906a-2cd6f1a90b13", &basistheory.UpdateReactorRequest{
Name: "My Updated Reactor",
Code: code,
Configuration: map[string]*string{
"SERVICE_API_KEY": basistheory.String("key_abcd1234"),
},
Runtime: &basistheory.Runtime{
Image: basistheory.String("node22"),
Dependencies: map[string]*string{
"maskdata": basistheory.String("1.3.2"),
"stripe": basistheory.String("18.4.0"),
"lodash": basistheory.String("4.17.21"),
},
Resolutions: map[string]*string{
"minimist": basistheory.String("1.2.8"),
},
Timeout: basistheory.Int(15),
Resources: basistheory.String("standard"),
WarmConcurrency: basistheory.Int(0),
Permissions: []string{"token:reveal", "token:create"},
},
})
URI Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
id | true | uuid | null | The ID of the reactor |
Request Parameters
| Attribute | Required | Type | Runtime | Description |
|---|---|---|---|---|
name | true | string | All | The name of the reactor. Has a maximum length of 200 |
code | true | string | All | Reactor code which will be executed when the Reactor is processed |
configuration | false | map<string, string> | All | A string key and string value map of predefined configuration names and values accessible from the Reactor code |
runtime | false | Runtime Object | All | Runtime configuration for the reactor. |
application.id | false | uuid | node-bt | This Application's API key is injected into a pre-configured BasisTheory JS SDK instance passed into the Reactor's runtime. Must be a public or private Application Type. |
Response
Returns a Reactor if the Reactor was updated. Returns an error if there were validation errors, or the Reactor failed to update.
- node-bt
- node22
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Reactor",
"code": "
module.exports = async function (req) {
// Do something with req.configuration.SERVICE_API_KEY
return {
raw: {
foo: 'bar'
}
};
};
",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"created_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"created_at": "2020-09-15T15:53:00+00:00",
"modified_by": "34053374-d721-43d8-921c-5ee1d337ef21",
"modified_at": "2021-03-01T08:23:14+00:00"
}
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"tenant_id": "77cb0024-123e-41a8-8ff8-a3d5a0fa8a08",
"name": "My Updated Reactor",
"state": "updating",
"code": "module.exports = async function (event) { ... }",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
},
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 10,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
},
"requested": {
"reactor": {
"code": "module.exports = async function (event) { ... }",
"runtime": {
"image": "node22",
"dependencies": {
"maskdata": "1.3.2",
"stripe": "18.4.0",
"lodash": "4.17.21"
},
"resolutions": {
"minimist": "1.2.8"
},
"timeout": 15,
"resources": "standard",
"warm_concurrency": 0,
"permissions": ["token:reveal", "token:create"]
}
}
},
"created_by": "fb124bba-f90d-45f0-9a59-5edca27b3b4a",
"created_at": "2020-09-15T15:53:00+00:00",
"modified_by": "34053374-d721-43d8-921c-5ee1d337ef21",
"modified_at": "2021-03-01T08:23:14+00:00"
}
node22 Vulnerability Failure Details
If a node22 deployment fails due to HIGH or CRITICAL dependency vulnerabilities, the Reactor includes vulnerability details in requested.
For create operations this is typically returned with state: "failed". For update operations this is typically returned with state: "outdated".
{
"id": "5b493235-6917-4307-906a-2cd6f1a90b13",
"state": "outdated",
"requested": {
"reactor": {
"code": "module.exports = async function (event) { ... }",
"runtime": {
"image": "node22",
"dependencies": {
"axios": "1.6.0"
}
}
},
"error_code": "vulnerabilities_detected",
"error_message": "Please update the dependencies listed to resolve security vulnerabilities.",
"error_details": {
"vulnerabilities": [
{
"name": "follow-redirects",
"version": "1.14.7",
"severity": "HIGH",
"id": "CVE-2022-0536",
"dependency_path": ["axios", "follow-redirects"]
}
]
}
}
}
For end-to-end scanning behavior and notifications, see Runtime Vulnerability Scanning.
Patch Reactor
Patch a Reactor by ID in the Tenant.
node22 updates are asynchronous. Check valid states where node22 can be updated.
Permissions
reactor:update
Content-Type header to be set to application/merge-patch+json. Requests made with a different Content-Type header value will receive a 415 Unsupported Media Type response code. For more information on merge-patch, see RFC 7386.Request
- node-bt
- node22
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
curl "https://api.basistheory.com/reactors/5b493235-6917-4307-906a-2cd6f1a90b13" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/merge-patch+json" \
-X "PATCH" \
-d '{
"name": "My Reactor",
"configuration": {
"SERVICE_API_KEY": "key_abcd1234"
}
}'
await client.reactors.patch(
reactorId,
{
name: "My Reactor",
configuration: {
SERVICE_API_KEY: "key_abcd1234",
}
}
)
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.patch(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
name: "My Reactor",
configuration: {
SERVICE_API_KEY: "key_abcd1234",
}
}
);
await client.Reactors.PatchAsync(
reactorId,
new PatchReactorRequest
{
Name = "My Reactor",
Configuration = new Dictionary<string, string?>
{
{ "SERVICE_API_KEY", "key_abcd1234" }
}
}
);
new ReactorsClient(ClientOptions.builder().build()).patch("id", PatchReactorRequest.builder()
.name("My Reactor")
.configuration(new HashMap() {{
put("SERVICE_API_KEY", "key_abcd1234");
}})
.build());
client.reactors.patch(
id = reactor_id,
name='My Reactor',
configuration={
"SERVICE_API_KEY": "key_abcd1234"
}
)
err := client.Reactors.Patch(ctx, reactorId, &basistheory.PatchReactorRequest{
Name: "My Reactor",
Configuration: map[string]*string{
"SERVICE_API_KEY": func(s string) *string { return &s }("key_abcd1234"),
},
})
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
javascript='module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Patched response",
masked_card: masked_card
},
statusCode: 200
}
};
};'
curl "https://api.basistheory.com/reactors/5b493235-6917-4307-906a-2cd6f1a90b13" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-H "Content-Type: application/merge-patch+json" \
-X "PATCH" \
-d '{
"code": '"$(echo $javascript | jq -Rsa .)"',
"runtime": {
"timeout": 20
}
}'
await client.reactors.patch(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Patched response",
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
runtime: {
timeout: 20,
}
}
)
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
const reactor = await bt.reactors.patch(
"5b493235-6917-4307-906a-2cd6f1a90b13",
{
code: `
module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Patched response",
masked_card: masked_card
},
statusCode: 200
}
};
};
`,
runtime: {
timeout: 20,
}
}
);
await client.Reactors.PatchAsync(
"5b493235-6917-4307-906a-2cd6f1a90b13",
new PatchReactorRequest
{
Code = @"
module.exports = async function (event) {
const MaskData = require('maskdata');
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: '*',
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: 'Patched response',
masked_card: masked_card
},
statusCode: 200
}
};
};",
Runtime = new Runtime
{
Timeout = 20
}
}
);
new ReactorsClient(ClientOptions.builder().build()).patch("5b493235-6917-4307-906a-2cd6f1a90b13", PatchReactorRequest.builder()
.code("...")
.runtime(Runtime.builder()
.timeout(20)
.build())
.build());
client.reactors.patch(
id="5b493235-6917-4307-906a-2cd6f1a90b13",
code="""module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Patched response",
masked_card: masked_card
},
statusCode: 200
}
};
};""",
runtime={
"timeout": 20
}
)
code := `module.exports = async function (event) {
const MaskData = require("maskdata");
const { card_number } = event.req;
const { SERVICE_API_KEY } = event.configuration;
const masked_card = MaskData.maskCard(card_number, {
maskWith: "*",
unmaskedStartDigits: 0,
unmaskedEndDigits: 4
});
return {
res: {
body: {
success: true,
message: "Patched response",
masked_card: masked_card
},
statusCode: 200
}
};
};`
err := client.Reactors.Patch(ctx, "5b493235-6917-4307-906a-2cd6f1a90b13", &basistheory.PatchReactorRequest{
Code: basistheory.String(code),
Runtime: &basistheory.Runtime{
Timeout: basistheory.Int(20),
},
})
URI Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
id | true | uuid | null | The ID of the reactor |
Request Parameters
| Attribute | Required | Type | Runtime | Description |
|---|---|---|---|---|
name | false | string | All | The name of the reactor. Has a maximum length of 200 |
code | false | string | All | Reactor code which will be executed when the Reactor is processed |
configuration | false | map<string, string> | All | A string key and string value map of predefined configuration names and values accessible from the Reactor code |
runtime | false | Runtime Object | All | Runtime configuration for the reactor. |
application.id | false | uuid | node-bt | This Application's API key is injected into a pre-configured BasisTheory JS SDK instance passed into the Reactor's runtime. Must be a public or private Application Type. |
Response
Returns 204 if successful. Returns an error if there were validation errors, or the operation failed.
Delete Reactor
Delete a Reactor by ID in the Tenant.
Check valid states where node22 can be deleted.
Permissions
reactor:delete
Request
- cURL
- Node
- JavaScript (legacy)
- C#
- Java
- Python
- Go
curl "https://api.basistheory.com/reactors/fb124bba-f90d-45f0-9a59-5edca27b3b4a" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>" \
-X "DELETE"
await client.reactors.delete("id");
import { BasisTheory } from "@basis-theory/basis-theory-js";
const bt = await new BasisTheory().init("<MANAGEMENT_API_KEY>");
await bt.reactors.delete("fb124bba-f90d-45f0-9a59-5edca27b3b4a");
await client.Reactors.DeleteAsync("id");
new ReactorsClient(ClientOptions.builder().build()).delete("id");
client.reactors.delete(
id="id",
)
err := client.Reactors.Delete(ctx, "id")
URI Parameters
| Parameter | Required | Type | Default | Description |
|---|---|---|---|---|
id | true | uuid | null | The ID of the reactor |
Response
Returns an error if the Reactor failed to delete.
Response
Returns a response object the same as the synchronous response.
Reactor Response Object
| Attribute | Type | Description |
|---|---|---|
tokens | object | (Optional) Token(s) created from the tokenize block of the Reactor code response |
raw | object | (Optional) Raw output returned from the Reactor |
Reactor Object
| Attribute | Type | Runtime | Description |
|---|---|---|---|
id | uuid | All | Unique identifier of the Reactor which can be used to get a Reactor |
tenant_id | uuid | All | The Tenant ID which owns the reactor |
name | string | All | The name of the reactor |
state | string | node22 | Current state of the reactor. See Reactor States |
code | string | All | Reactor code which will be executed when the Reactor is processed. |
configuration | map<string, string> | All | A string key and string value map of predefined configuration names and values accessible from the Reactor code. |
runtime | Runtime Object | All | Runtime configuration. |
requested | Requested Object | node22 | Contains pending configuration at requested.reactor and provisioning error details during asynchronous provisioning. Present when state is creating or updating, and can also be present in failed or outdated when the latest deployment did not succeed. |
application | Application | node-bt | This Application's API key is injected into a pre-configured BasisTheory JS SDK instance passed into the Reactor's runtime. Must be a public or private Application Type. |
created_by | uuid | All | (Optional) The ID of the user or Application that created the Reactor |
created_at | string | All | (Optional) Created date of the Reactor in ISO 8601 format |
modified_by | uuid | All | (Optional) The ID of the user or Application that last modified the Reactor |
modified_at | date | All | (Optional) Last modified date of the Reactor in ISO 8601 format |
Requested Object
The requested object contains pending Reactor configuration during asynchronous provisioning, and failure details when that pending deployment does not complete successfully.
| Attribute | Type | Description |
|---|---|---|
reactor | object | Pending Reactor configuration for the most recent asynchronous provisioning request. See Pending Reactor Object. |
error_code | string | Public error code for provisioning failures (for example, vulnerabilities_detected). |
error_message | string | Public error message for provisioning failures. |
error_details | object | Additional structured details for the failure. Present for error codes that expose details (for example vulnerability findings). |
Pending Reactor Object
| Attribute | Type | Description |
|---|---|---|
code | string | The pending Reactor code. |
runtime | Runtime Object | The pending runtime configuration. |
configuration | map<string, string> | The pending configuration key-values. |
Vulnerability Error Details
When requested.error_code is vulnerabilities_detected, requested.error_details includes a vulnerabilities array:
| Attribute | Type | Description |
|---|---|---|
error_details.vulnerabilities | array | List of detected vulnerabilities. |
vulnerabilities[].name | string | Vulnerable package name. |
vulnerabilities[].version | string | Vulnerable package version. |
vulnerabilities[].severity | string | Vulnerability severity (LOW, MEDIUM, HIGH, CRITICAL). |
vulnerabilities[].id | string | Vulnerability identifier (for example CVE). |
vulnerabilities[].dependency_path | array | Dependency chain from direct dependency to the vulnerable package. |
Runtime Object
The runtime object configures the execution environment.
| Attribute | Required | Type | Default | Runtime | Description |
|---|---|---|---|---|---|
image | true | string | - | All | The runtime image identifier. See available runtimes. |
dependencies | false | map<string, string> | {} | node22 | npm packages to install. Key is package name, value is an exact pinned version (e.g., "stripe": "18.4.0"). |
resolutions | false | map<string, string> | {} | node22 | Dependency version overrides applied at build time. Use to override versions of dependencies installed indirectly through other packages. |
timeout | false | number | 10 | node22 | Maximum execution time in seconds (1-30). |
resources | false | string | standard | node22 | Compute resources allocation. One of standard, large, xlarge. |
warm_concurrency | false | number | 0 | node22 | Number of warm instances to maintain. |
permissions | false | array<string> | [] | node22 | Basis Theory permissions to grant (e.g., token:reveal, token:create). |
See Runtime Options for detailed descriptions of each property.
Code Contract
For details on writing reactor code, including request/response objects and examples, see Code Contract.
Runtime Options
For details on configuring the runtime object, including dependencies, resolutions, timeout, resources, warm concurrency, and permissions, see node22 Runtime Options.