Twisp
Branching Tenants and Managing Aliases
Create stable tenant aliases, copy configuration into branch tenants, and move an alias to a new branch.
Use a tenant alias when clients need a stable name, such as twisp-dev, while the tenant behind that name changes over time. Use a branch when you need a new, isolated tenant containing configuration copied from an existing tenant.
Together, branching and aliases support a workflow like this:
- Create an alias for the current development tenant.
- Branch the tenant's configuration into a new tenant.
- Validate the branch using its generated
accountId. - Repoint the alias when the branch is ready.
Aliases are unique per region. An alias can point only to a tenant in its owning organization, and only that organization can update or delete it.
Before you begin
Send these mutations to the GraphQL endpoint in the region containing the source tenant:
https://api.<region>.cloud.twisp.com/financial/v1/graphql
Authenticate the request and identify the source tenant with an explicit account ID:
authorization: Bearer <JWT>
content-type: application/json
x-twisp-account-id: <source-account-id>
Using a literal value in x-twisp-account-id for administrative requests keeps the source tenant explicit while an alias is being moved. For ordinary requests, clients can put a qualified alias in the same header, such as x-twisp-account-id: alias/twisp-dev.
Alias fields in the GraphQL API use the raw alias name, such as twisp-dev. When an alias is supplied through x-twisp-account-id, qualify it as alias/twisp-dev so the server can distinguish it from a literal account ID. The alias/ prefix is not stored and is not returned by alias queries or mutations.
| Input | Value | Behavior |
|---|---|---|
GraphQL alias field | twisp-dev | Creates, updates, or identifies the raw alias name |
x-twisp-account-id | twisp-dev | Uses twisp-dev as a literal account ID |
x-twisp-account-id | alias/twisp-dev | Resolves the alias twisp-dev |
The caller needs the following permissions:
- Creating an alias requires
db:Insertonfinancial.aliases. - Branching requires
db:Insertonfinancial.tenantsand permission to select and insert each configuration class being copied.
1. Create an alias
Create the alias in the same region as its target tenant. The target accountId must belong to the caller's organization.
Alias names and tenant account IDs follow the S3 bucket naming rules:
- 3 to 63 characters.
- Lowercase letters, numbers, periods (
.), and hyphens (-) only. - Begins and ends with a letter or a number.
- No two adjacent periods.
- Not formatted as an IP address, such as
192.168.5.4.
A tenant account ID has one further restriction: it cannot begin with alias. This keeps an account ID from being read as the qualified form that x-twisp-account-id accepts. An alias name may begin with alias.
mutation CreateAlias($alias: String!, $accountId: String!, $ttlSeconds: Int = 60) {
admin {
createAlias(
input: {
alias: $alias
accountId: $accountId
ttlSeconds: $ttlSeconds
}
) {
alias
accountId
organizationId
region
ttlSeconds
}
}
}
{
"alias": "twisp-dev",
"accountId": "4b3aef43-e770-4a51-aa8f-f73421f7045e",
"ttlSeconds": 60
}
The mutation returns twisp-dev in its alias field. To address the tenant, qualify that name in the account ID header:
curl 'https://api.<region>.cloud.twisp.com/financial/v1/graphql' \
-H 'authorization: Bearer <JWT>' \
-H 'content-type: application/json' \
-H 'x-twisp-account-id: alias/twisp-dev' \
--data-raw '{"query":"query CurrentOrganization { admin { organization { id name } } }"}'
2. Point an alias at a different tenant
Use updateAlias to move an existing alias to another tenant in the same organization. The alias name and owning organization do not change.
mutation RepointAlias($alias: String!, $accountId: String!, $ttlSeconds: Int = 60) {
admin {
updateAlias(
input: {
alias: $alias
accountId: $accountId
ttlSeconds: $ttlSeconds
}
) {
alias
accountId
region
ttlSeconds
}
}
}
{
"alias": "twisp-dev",
"accountId": "066dbb42-42d9-4605-a010-428b46c766c7",
"ttlSeconds": 60
}
Alias resolutions are cached. Updating ttlSeconds controls future cache entries; it does not invalidate an old mapping that a server has already cached. For a planned cutover, first lower the alias TTL, wait at least the previous TTL, and then repoint the alias. Raise the TTL again after the cutover is visible.
3. Branch a tenant
branch generates a new tenant accountId and copies configuration from the tenant identified by the request header.
mutation BranchTenant {
admin {
branch(input: {}) {
id
accountId
organizationId
name
description
}
}
}
An empty BranchInput copies all supported configuration classes:
- calculations
- custom indexes
- endpoints
- non-default journals
- tran codes
- velocity controls and their configuration memberships
- views and their backing table definitions
- customer-defined clients
Accounts, balances, entries, and transactions are not copied. Tenant creation supplies the new tenant's default journal and Twisp-managed clients.
To copy only selected configuration, provide include:
mutation BranchSelectedConfiguration {
admin {
branch(input: { include: [Journal, TranCode, Calculation] }) {
accountId
}
}
}
The available values are Calculation, CustomIndex, Endpoint, Journal, TranCode, VelocityControl, and View. Include View when copying a custom index defined on a view.
The branch operation is synchronous. Large configurations may take longer than a typical unary request deadline.
4. Branch and point an alias to the new branch
Twisp's @export directive can capture the generated branch accountId and pass it to a later field in the same mutation. Top-level mutation fields execute serially, so keep the branch field before the alias update.
mutation BranchAndRepointAlias($accountId: String = "") {
branch: admin {
branch(input: {}) {
accountId @export(as: "accountId")
}
}
moveAlias: admin {
updateAlias(
input: {
alias: "twisp-dev"
accountId: $accountId
ttlSeconds: 1
}
) {
alias
accountId
region
ttlSeconds
}
}
}
The initial value of $accountId satisfies GraphQL variable validation. @export replaces it with the generated branch account ID before moveAlias executes.
Branch creation and alias updates commit through independent administrative transactions. If the branch succeeds but updateAlias fails, the branch remains and the alias continues pointing at its previous tenant. Use separate mutations when your workflow needs to retain the generated branch ID for explicit retry and recovery.
For a planned low-downtime switch:
- Lower the current alias TTL and wait out its previous TTL.
- Branch the source tenant.
- Test the new tenant using its explicit
accountId. - Repoint the alias to the branch.
- After the switch is visible, restore the normal alias TTL.