Deprecations
Deprecated Features
The following table lists deprecated features and their respective shutdown dates.
Feature | Deprecated Date | Shutdown Date | Details |
---|---|---|---|
List Tokens v1 | January 3, 2025 | March 1, 2025 | List Tokens v1 has been replaced by List Tokens v2. See the section below on Migrating to List Tokens v2. |
Search Tokens v1 | January 3, 2025 | March 1, 2025 | Search Tokens v1 has been replaced by Search Tokens v2. See the section below on Migrating to Search Tokens v2. |
Async Reactor callback_url | November 1, 2024 | January 15, 2025 | Async Reactors will no longer support the callback_url attribute. For more information, see the section below on Async Reactor callback_url Deprecation. |
Legacy Rate Limits | June 10, 2024 | July 16, 2024 | Legacy Rate Limits have been updated as documented here. |
Application Key Regenerate | April 17, 2024 | October 17, 2024 | Regenerating API Keys for an Application has been replaced with the ability to have multiple Application Keys per Application. Equivalent behavior can be achieved by creating a new Application Key and removing the old key. |
Complex Token Search Queries | January 23, 2024 | January 23, 2024 | Search Tokens no longer supports complex Lucene queries. See the section below on Complex Token Search Deprecation. |
Reactor Formulas | October 16, 2023 | February 14, 2024 | Reactor Formulas have been deprecated in favor of Reactors with code . For more information, see the section below on Migrating from Reactor Formulas. |
request_reactor_id and response_reactor_id removed from Proxies | November 30, 2022 | March 31, 2023 | In order to simplify management of Proxies, use of request_transform and response_tramsform has been recommended over Reactors. |
Token Privacy Settings | October 13, 2022 | February 1, 2023 | Privacy settings (i.e. classification, impact level, and restriction policy) have been deprecated and replaced by a more flexible authorization model based upon Containers and Access Rules. For more information, see the section below on Migrating from Privacy Settings. |
Migrating to List Tokens v2
The List Tokens v1 endpoint has been deprecated and replaced by List Tokens v2. The following changes are required to migrate to the v2 endpoint:
- Change from offset pagination to cursor pagination.
- Requests containing the
id
query parameter are no longer supported.- Use the Get Token endpoint to retrieve a single token by id.
- Use the Detokenize endpoint to retrieve multiple tokens by their ids.
- Requests containing multiple metadata query parameters are no longer supported, e.g.
GET /tokens?metadata.type=phone&metadata.customer_id=1234
- Migration Strategy 1: Client side filtering
- Migration Strategy 2: Alias tokens
- Migration Strategy 3: Combine metadata
- Metadata queries are no longer case-insensitive. Update your queries to perform a case-sensitive exact match on key and value.
Migrating to Search Tokens v2
The Search Tokens v1 endpoint has been deprecated and replaced by Search Tokens v2. The following changes are required to migrate to the v2 endpoint:
- Change from offset pagination to cursor pagination.
- Queries containing the
id
field are no longer supported.- Use the Get Token endpoint to retrieve a single token by id.
- Use the Detokenize endpoint to retrieve multiple tokens by their ids.
- Queries combining multiple metadata terms are no longer supported, e.g.
metadata.type:phone AND metadata.customer_id:1234
- Migration Strategy 1: Client side filtering
- Migration Strategy 2: Alias tokens
- Migration Strategy 3: Combine metadata
- Metadata queries are no longer case-insensitive. Update your queries to perform a case-sensitive exact match on key and value.
Client side filtering
Remove one of the metadata terms from the query
and filter the search results by the other property once returned to your system:
Original Search Query: metadata.type:phone AND metadata.customer_id:1234
New Query: metadata.customer_id:1234
Filter in your system: metadata.type = "phone"
Alias tokens
Use Aliases to create a single identifier from the multiple terms currently required in a query
.
Example:
A query with the following multiple terms:
metadata.type:phone AND metadata.customer_id:1234
Can be converted to the following Alias when creating a token:
{
"id": "1234_phone",
...
}
Now systems are capable of requesting this token by the id
attribute:
GET /tokens/1234_phone
This approach will require migrating existing tokens to the new alias.
Combine metadata
Combine the multiple terms into a single metadata
field and continue to use the query
with a single term:
Original metadata
field:
{
"type": "phone",
"customer_id": "1234"
}
New metadata
field:
{
"type": "phone",
"customer_id": "1234",
"type_customer_id": "phone_1234"
}
Original Search Query: metadata.type:phone AND metadata.customer_id:1234
New Query: metadata.type_customer_id:phone_1234
This approach will require migrating existing tokens to add the new combined metadata field.
Async Reactor callback_url
Deprecation
Async Reactors will no longer support the callback_url
attribute and will be replaced by the Reactor Webhooks Events.
To migrate your Async Reactors, you will need to:
- Create a new Webhook either with our Management API/Terraform Provider or in the Portal.
- You may be able to use the existing URL for your rector processing
- Invoke a Reactor Asynchronously with the new
/reactors/:id/react-async
endpoint. - Once your webhook is invoked, retrieve the Async Reactor Results
- This ensures the system receiving the webhook has access to the results of the reactor.
- Process the results in the same way you are currently doing with the
callback_url
To coordinate a rollout of these changes, we suggest you stop sending requests with callback_url
and change the request path from /react
to /react-async
when you roll out the new webhook handler code. This will avoid any overlap or duplication of processing.
Migrating to New Rate Limits
Learn more about these Rate Limit changes in our blog Introducing New Rate Limits.
Production Tenants
- Private Applications
- You must rotate Private API keys to the new format to maintain your existing Rate Limits.
- Public and Management Applications
- While it is suggested to rotate these keys, this is an option to change for these Applications - based on our findings, no active customers will see any reduction in service.
- Whitelabel Proxies
- No action is required for these tenants
- Reactors
- If your Reactor specifies an Application, you'll need to generate a new key for that application to ensure it has the correct rate limit. No other change is required.
Test Tenants
No changes are required for Test Tenants. If you need a higher rate limit for these tenants, please contact support@basistheory.com
or your account representative.
How to rotate your Private API keys
Rotate via our Portal
If you created your keys via the Portal - follow this guide:
- Go to the Applications List
- Find the Applications needing keys rotated and click the "edit" icon ✏️.
- In the Application details page, find the "API Keys" section and create a new API Key. (Don't worry, this will not stop the existing keys from working.)
- Copy the new generated key and update your systems with the new value.
- Once you are done updating all your systems with the new value, click the "trash" 🗑️ icon to delete the "Legacy" key. (Only do this once all usages of the keys have been updated)
Rotate via Terraform
You are able to manage API Keys via Terraform with the Guide found in v2 of our Terraform Provider.
- Create a new key for the Applications
- Update your systems with the new key
- Once all systems have been updated, delete the old key
Old Rate Limit Deprecation
The existing rate limits will be deprecated in favor of new rate limits capable of being customized.
- Globale Rate Limit
- Counter: IP
- Rate: 1000 Requests / 10 Seconds
- Block Duration: 10 Seconds
- Portal:
- Counter: IP
- Rate: 600 Requests / 10 Seconds
- Block Duration: 10 Seconds
- API
- POST /tokens/search
- Counter: IP
- Rate 50 Requests / 10 Seconds
- Block Duration: 10 Seconds
- GET /tokens
- Counter: IP
- Rate 100 Requests / 10 Seconds
- Block Duration: 10 Seconds
- POST (/tokens | /tokenize)
- Counter: IP
- Rate 200 Requests / 10 Seconds
- Block Duration: 10 Seconds
- POST /tokens/search
Application Key Regenerate Deprecation
Regenerating an application's API key used to involve calling the Regenerate
endpoint on the Application. With the introduction of Application keys, this functionality has been replaced with the ability to create new Application Keys and remove the old key.
To recreate the Regeneration action you'll need to:
Complex Token Search Deprecation
The token search endpoint POST /tokens/search no longer supports complex Lucene queries in the query
parameter.
Deprecated Query Patterns
- The following token fields are no longer supported within search queries:
type
,fingerprint
,container
,created_by
,created_at
,modified_by
,modified_at
. - Mixed search terms containing mixed attributes, e.g.
metadata.customer_id:1234 AND type:card
. - Combining terms with the
OR
operator. TheAND
operator is only supported for multi-metadata search. - Term negation is not supported.
Supported Query Patterns
- Filtering by a single
id
,metadata.<key>
, ordata
term - Filtering by multiple
metadata.<key>
terms combined with anAND
operator, e.g.metadata.type:phone AND metadata.customer_id:1234
Migrating From Privacy Settings
Privacy settings were previously used to scope access to Tokens based on their data classification and impact levels.
In order to provide a more flexible access control model that can be customized per Application, we have introduced
Token Containers
to logically group Tokens according to any data governance requirements. A Token may be explicitly added to a container
when creating the Token, or if unspecified, a Token will be placed within the container /<classification>/<impact_level>/
by default. If you were previously customizing a Token's classification or impact level, please update your systems to
directly set the containers
attribute instead.
Restriction policies were previously used in conjunction with impact level based read
permissions (e.g., token:general:read:low
) to define how Token data should be transformed when reading Tokens with
a higher impact level than your permission allows. This model proved to be too inflexible as it was a global setting
applied at the Token level and could not be customized per actor. Restriction policies no longer have any functional
impact, and were replaced by transforms applied via Access Rules.
If your systems are using the privacy
attribute of the Token Object in API responses, please
update your integration to ignore this attribute as it will be removed on February 1, 2023.
Migrating From Reactor Formulas
Reactor Formulas were how you added code to a Reactor and configured some of its behavior.
To offer less friction when creating Reactors, we have introduced a new code
attribute to the Reactor Object.
This attribute is a string
containing the code that will be executed when the Reactor is triggered.
Alongside not having to create a new formula for each Reactor with different code, this new approach also removes some previous restrictions on configuration
and request_parameters
.
Reactors with code
will not provide validation of the configuration
attribute or its request parameters, so you will need to perform this validation directly in your code if necessary.
If your systems are using the formula
attribute of the Reactor Object in API responses, please update to use code
instead.
This can be done simply by taking the value for the code
attribute on the formula and setting it as the value for the code
attribute on the Reactor.
Below there are some examples on how this operation can be performed by retrieving the formula object and performing a [patch operation] in the Reactor:
- cURL
- Node
- C#
- Java
- Python
- Go
curl "https://api.basistheory.com/reactor-formulas/17069df1-80f4-439e-86a7-4121863e4678" \
-H "BT-API-KEY: <MANAGEMENT_API_KEY>"
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"
);
const reactorFormula = await bt.reactorFormulas.retrieve(reactor.formula.id);
const patchedReactor = await bt.reactors.patch(reactor.id,
{
code: reactorFormula.code,
}
);
using BasisTheory.net.Reactors;
using BasisTheory.net.ReactorFormulas;
var reactorClient = new ReactorClient("<MANAGEMENT_API_KEY>");
var reactor = await reactorClient.GetByIdAsync("5b493235-6917-4307-906a-2cd6f1a90b13");
var formulaClient = new ReactorFormulaClient("<MANAGEMENT_API_KEY>");
var reactorFormula = await formulaClient.GetByIdAsync(reactor.Formula.Id);
var patchedReactor = await reactorClient.PatchAsync(Reactor.Id,
new Reactor {
Code = reactorFormula.Code
});
import com.basistheory.*;
import com.basistheory.auth.*;
import java.util.UUID;
public class Example {
public static void main(String[] args) throws Exception {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("https://api.basistheory.com");
ApiKeyAuth ApiKey = (ApiKeyAuth) defaultClient.getAuthentication("ApiKey");
ApiKey.setApiKey("<MANAGEMENT_API_KEY>");
ReactorsApi apiInstance = new ReactorsApi(defaultClient);
Reactor reactor = apiInstance.getById(UUID.fromString("5b493235-6917-4307-906a-2cd6f1a90b13"));
ReactorFormulasApi apiInstance = new ReactorFormulasApi(defaultClient);
ReactorFormula reactorFormula = apiInstance.getById(reactor.getFormula().getId());
PatchReactorRequest patchReactorRequest = new PatchReactorRequest();
Reactor patchedReactor = apiInstance.patch(reactor.getId(), patchReactorRequest
.code(reactorFormula.getCode()));
}
}
import basistheory
from basistheory.api import reactors_api
from basistheory.api import reactor_formulas_api
with basistheory.ApiClient(configuration=basistheory.Configuration(api_key="<MANAGEMENT_API_KEY>")) as api_client:
reactors_client = reactors_api.ReactorsApi(api_client)
reactor = reactors_client.get_by_id("5b493235-6917-4307-906a-2cd6f1a90b13")
reactor_formulas_client = reactor_formulas_api.ReactorFormulasApi(api_client)
reactor_formula = reactor_formulas_client.get_by_id(reactor.formula.id)
patched_reactor = reactors_client.patch(reactor.id, patch_reactor_request=PatchReactorRequest(
code=reactor_formula.code
))
package main
import (
"context"
"github.com/Basis-Theory/basistheory-go/v3"
)
func main() {
configuration := basistheory.NewConfiguration()
apiClient := basistheory.NewAPIClient(configuration)
contextWithAPIKey := context.WithValue(context.Background(), basistheory.ContextAPIKeys, map[string]basistheory.APIKey{
"ApiKey": {Key: "<MANAGEMENT_API_KEY>"},
})
reactor, httpResponse, err := apiClient.ReactorsApi.GetById(contextWithAPIKey, "5b493235-6917-4307-906a-2cd6f1a90b13").Execute()
reactorFormula, httpResponse, err := apiClient.ReactorFormulasApi.GetById(contextWithAPIKey, reactor.GetFormula().GetId()).Execute()
patchReactorRequest := *basistheory.NewPatchReactorRequest()
patchReactorRequest.SetCode(reactorFormula.GetCode())
patchedReactor, httpResponse, err := apiClient.ReactorsApi.Patch(contextWithAPIKey, reactor.GetId()).PatchReactorRequest(patchReactorRequest).Execute()
}
You can continue to use your existing Reactors with formula
until they are removed on a future date, but we advise you to migrate to code
as soon as possible.
Keep in mind that after migrating to code
the formula
will be removed from the Reactor but can still be retrieved for consulting purposes until the shutdown date.
Async Reactor callback_url
Deprecation
Async Reactors will no longer support the callback_url
attribute and will be replaced by the Reactor Webhooks Events.
To migrate your Async Reactors, you will need to:
- Create a new Webhook either with our Management API/Terraform Provider or in the Portal.
- You may be able to use the existing URL for your rector processing
- Invoke a Reactor Asynchronously with the new
/reactors/:id/react-async
endpoint. - Once your webhook is invoked, retrieve the Async Reactor Results
- This ensures the system receiving the webhook has access to the results of the reactor.
- Process the results in the same way you are currently doing with the
callback_url
To coordinate a rollout of these changes, we suggest you stop sending requests with callback_url
and change the request path from /react
to /react-async
when you roll out the new webhook handler code. This will avoid any overlap or duplication of processing.
Legacy Server-Side SDKs
The following server-side SDKs have been deprecated. New API endpoints will not be added to the deprecated SDKs. Support for the Legacy SDKs will end January 1, 2025.
Language | Deprecated | Current |
---|---|---|
node | basis-theory-js Github | node-sdk Docs |
dotnet | basistheory-dotnet Github | dotnet-sdk Docs |
java | basistheory-java Github | java-sdk Docs |
python | basistheory-python Github | python-sdk Docs |
go | basistheory-go Github | go-sdk Docs |
Documentation for the legacy SDKs can be found in their Github repositories.
The basis-theory-js
SDK will continue to be supported for web and reactor usage.
Documentation for basis-theory-js
can be found in the JavaScript (legacy)
code tabs throughout this site.