GraphQL

Mutations

Mutations modify or create data on the ledger or execute admin actions by specifying the operation to be performed and the input data.

addToAccountSet

Add a new member to a set. Members can be an Account or another AccountSet.

Resolves to

AccountSet!

Arguments

id - UUID! Unique identifier for set.
member - AccountSetMemberInput! Account or AccountSet to add as a member of this set.

Example

mutation AddToAccountSet(
  $accountSetCustomersId: UUID!
  $accountCustomerAliciaId: UUID!
) {
  addToAccountSet(
    id: $accountSetCustomersId
    member: { memberId: $accountCustomerAliciaId, memberType: ACCOUNT }
  ) {
    accountSetId
    members(first: 10) {
      nodes {
        ... on Account {
          accountId
          name
          code
        }
      }
    }
  }
}

admin

Mutations in the admin namespace are used to manage the organization data like users, groups, and tenants.

createGroup

Create a new group.

Resolves to

Group

Arguments

input - CreateGroupInput! Fields to create a new group.

Example

mutation AdminCreateGroup {
  admin {
    createGroup(
      input: {
        id: "917e123a-b89d-4ab5-b11c-cdf6aac80b63"
        name: "empty-policy-1"
        description: "A group with an empty policy"
        policy: "[]"
      }
    ) {
      name
      description
      policy
    }
  }
}

createTenant

Create a new tenant.

Resolves to

Tenant

Arguments

input - CreateTenantInput! Fields to create a new tenant.

Example

mutation AdminCreateTenant {
  admin {
    createTenant(
      input: {
        id: "72a0097f-239e-48ec-a417-49c318332ed6"
        accountId: "sandbox"
        name: "Sandbox"
        description: "Sandbox tenant for testing"
      }
    ) {
      accountId
      name
    }
  }
}

createUser

Create a new human user.

Upon creation, new users will receive an invite email to sign in to Twisp Console.

Resolves to

User

Arguments

input - CreateUserInput! Fields to create a new user.

Example

mutation AdminCreateUser {
  admin {
    createUser(
      input: {
        id: "9cc8bd28-a36d-502e-89fd-7f1410c1b90a"
        groupIds: ["d57bd759-73d5-4452-a73e-12b590324e35"]
        email: "george@twisp.com"
      }
    ) {
      id
      email
      groupIds
    }
  }
}

deleteGroup

Delete an existing group.

Resolves to

Group

Arguments

name - String! Name of group to delete.

Example

mutation AdminDeleteGroup {
  admin {
    deleteGroup(name: "empty-policy-1") {
      name
    }
  }
}

deleteTenant

Delete an existing tenant.

Resolves to

Tenant

Arguments

accountId - String! Unique identifier.

Example

mutation AdminDeleteTenant {
  admin {
    deleteTenant(accountId: "sandbox") {
      accountId
    }
  }
}

deleteUser

Delete an existing human user.

Resolves to

User

Arguments

email - String! Email of user to delete.

Example

mutation AdminDeleteUser {
  admin {
    deleteUser(email: "george@twisp.com") {
      email
    }
  }
}

updateGroup

Update an existing group. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Group

Arguments

input - UpdateGroupInput! Fields to update.

Example

mutation AdminUpdateGroup {
  admin {
    updateGroup(
      input: {
        name: "empty-policy-1"
        description: "An empty policy layer will default to the base policy."
        policy: "[{\"actions\": [\"*\"],\"effect\": \"DENY\",\"resources\":[\"*\"], \"assertions\": {\"always false\": \"1 == 0\"}}]"
      }
    ) {
      name
      description
      policy
    }
  }
}

updateTenant

Update an existing tenant. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Tenant

Arguments

input - UpdateTenantInput! Fields to update.

Example

mutation AdminUpdateTenant {
  admin {
    updateTenant(
      input: {
        accountId: "sandbox"
        description: "This is the sandbox tenant."
      }
    ) {
      accountId
      description
      version
    }
  }
}

updateUser

Update an existing human user. To ensure data integrity, only a subset of fields are allowed.

Resolves to

User

Arguments

input - UpdateUserInput! Fields to update.

Example

mutation AdminUpdateUser {
  admin {
    updateUser(
      input: {
        email: "george@twisp.com"
        groupIds: ["152f0c89-6cba-53c9-955e-16d7cbc1f35e"]
      }
    ) {
      email
      groupIds
    }
  }
}

auth

Mutations in the auth namespace are used to manage clients and their policies. Use the createClient mutation to create a new client, updateClient to update an existing client, and deleteClient to delete a client.

createClient

Create a new security client.

Resolves to

Client!

Arguments

Example

mutation CreateAuthClient($authClientGithub: String!) {
  auth {
    createClient(
      input: {
        principal: $authClientGithub
        name: "Github"
        policies: [
          {
            effect: ALLOW
            actions: [SELECT, INSERT, UPDATE, DELETE]
            resources: ["financial.*"]
            assertions: { isTrue: "true" }
          }
        ]
      }
    ) {
      principal
    }
  }
}

deleteClient

Delete a security client.

Resolves to

Client

Arguments

principal - String! Principal to delete.

Example

mutation DeleteAuthClient($authClientGithub: String!) {
  auth {
    deleteClient(principal: $authClientGithub) {
      principal
    }
  }
}

updateClient

Update an existing client by replacing policies.

Resolves to

Client

Arguments

principal - String! Principal of the client to update.
input - UpdateClientInput! Client fields to update.

Example

mutation UpdateAuthClient($authClientGithub: String!) {
  auth {
    updateClient(
      principal: $authClientGithub
      input: {
        policies: [
          {
            effect: ALLOW
            actions: [SELECT, INSERT]
            resources: ["financial.*"]
            assertions: { isTrue: "true" }
          }
        ]
      }
    ) {
      policies {
        effect
        actions
        resources
        assertions
      }
    }
  }
}

bulk

execute

Resolves to

BulkQueryExecution

Arguments

cards

Mutations in the cards namespace are used to initialize card processing transaction codes, including specific implementations like the Lithic card processing webhook.

initializeCardTransactionCodes

Initialize your Twisp instance with Card Processing Transaction Codes. Returns the default settlement account.

Resolves to

Account!

Arguments

Example

mutation InitializeCardTransactionCodes($journalGLId: UUID!) {
  cards {
    initializeCardTransactionCodes(input: { journalId: $journalGLId }) {
      accountId
      name
      code
    }
  }
}

postLithicTransaction

This mutation supports converting Lithic Transaction Webhooks JSON into into Twisp accounting core using our card transaction codes.

This mutation supports all lithic transaction webhook payloads, including ASA and Balance Inquiry. The general approach is to post all webhooks to Twisp, utilize the balances that come back for decisioning, and allow Twisp and Lithic to work together to track the state of the authorization/settlement cycle.

Resolves to

LithicTransactionBalance!

Arguments

createAccount

Create a new account.

Resolves to

Account!

Arguments

input - AccountInput! Fields to create a new account.

Example

mutation CreateAccount($accountCardSettlementId: UUID!) {
  createAccount(
    input: {
      accountId: $accountCardSettlementId
      name: "Card Settlement"
      code: "SETTLE.CARD"
      description: "Settlement account for card transactions."
      normalBalanceType: CREDIT
      status: ACTIVE
    }
  ) {
    accountId
    name
    code
    description
    normalBalanceType
  }
}

createAccountSet

Create a new account set.

Resolves to

AccountSet!

Arguments

input - AccountSetInput! Fields to create a new account set.

Example

mutation CreateAccountSet($accountSetCustomersId: UUID!, $journalGLId: UUID!) {
  createAccountSet(
    input: {
      accountSetId: $accountSetCustomersId
      journalId: $journalGLId
      name: "Customers"
      description: "All customer wallets."
      normalBalanceType: DEBIT
    }
  ) {
    accountSetId
    name
    description
  }
}

createCalculation

Create a calculation, which allows for balances to be customized on dimensions/filters.

Resolves to

Calculation!

Arguments

Example

mutation CreateCalculation {
  createCalculation(
    input: {
      calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5"
      code: "EFFECTIVE_DATE"
      description: "Track balances per EFFECTIVE_DATE in an account."
      dimensions: [
        { alias: "effectiveDate", value: "context.vars.transaction.effective" }
      ]
    }
  ) {
    calculationId
    code
    description
    dimensions {
      alias
      value
    }
  }
}

createJournal

Create a new journal for recording transactions in the ledger.

Resolves to

Journal!

Arguments

input - JournalInput! Fields to create a new Journal.

Example

mutation CreateJournal($journalGLId: UUID!) {
  createJournal(
    input: {
      journalId: $journalGLId
      name: "GL"
      description: "General Ledger"
      status: ACTIVE
    }
  ) {
    journalId
    name
    description
    status
  }
}

createTranCode

Create a new transaction code (tran code).

Resolves to

TranCode!

Arguments

input - TranCodeInput! Fields to create a new TranCode.

Example

mutation CreateTranCode(
  $tcBookTransferId: UUID!
  $journalGLIdExp: Expression!
) {
  createTranCode(
    input: {
      tranCodeId: $tcBookTransferId
      code: "BOOK_TRANSFER"
      description: "Book transfer between two internal accounts."
      metadata: { category: "Internal" }
      params: [
        { name: "crAccount", type: UUID, description: "Account to credit." }
        { name: "drAccount", type: UUID, description: "Account to debit." }
        {
          name: "amount"
          type: DECIMAL
          description: "Amount with decimal, e.g. `1.23`."
        }
        {
          name: "currency"
          type: STRING
          description: "Currency used for transaction."
        }
        {
          name: "effective"
          type: DATE
          description: "Effective date for transaction."
        }
      ]
      transaction: {
        journalId: $journalGLIdExp
        effective: "params.effective"
        description: "'Book transfer for $' + string(params.amount)"
      }
      entries: [
        {
          accountId: "params.drAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_DR'"
          direction: "DEBIT"
          layer: "SETTLED"
        }
        {
          accountId: "params.crAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_CR'"
          direction: "CREDIT"
          layer: "SETTLED"
        }
      ]
    }
  ) {
    tranCodeId
  }
}

deleteAccount

Delete account moves the account state to LOCKED. When an account is in LOCKED, prevents entries from being posted to it.

Resolves to

Account

Arguments

id - UUID! Unique identifier.

Example

mutation DeleteAccount($accountCustomerBobbyId: UUID!) {
  deleteAccount(id: $accountCustomerBobbyId) {
    accountId
    status
  }
}

deleteAccountSet

Delete an account set.

Resolves to

AccountSet

Arguments

id - UUID! Unique identifier.

Example

mutation DeleteAccountSet($accountSetCustomersId: UUID!) {
  deleteAccountSet(id: $accountSetCustomersId) {
    accountSetId
  }
}

deleteCalculation

Delete calculation. Must remove all attachments first.

Resolves to

Calculation

Arguments

id - UUID! Unique identifier.

Example

mutation DeleteCalculation {
  deleteCalculation(id: "5867b5dd-fc69-416c-80f5-62e8a53610d5") {
    calculationId
  }
}

deleteJournal

Moves journal into LOCKED status. Prevents entries from being posted to the journal.

Resolves to

Journal

Arguments

id - UUID! Unique identifier.

Example

mutation DeleteJournal($journalGLId: UUID!) {
  deleteJournal(id: $journalGLId) {
    journalId
    status
  }
}

deleteTranCode

Moves the tran code into LOCKED status. Prevents transactions from posting using this version of tran code.

Resolves to

TranCode

Arguments

id - UUID! Unique identifier.

Example

mutation DeleteTranCode($tcBookTransferId: UUID!) {
  deleteTranCode(id: $tcBookTransferId) {
    tranCodeId
    status
  }
}

evaluate

Evaluate a CEL (common expression language) expression using Twisp's calculation engine. Returns a String representation of the evaluated result.

Resolves to

Value!

Arguments

expressions - ExpressionMap! A map of literal Cel expressions to be evaluated in a shared context Ex: { "two": "this.one + 1", "one": "2 - 1", "sqrt2": "math.Sqrt(double(2))", "now": "time.Now()" }
document - Value Value object. Similar to the JSON object with support for type coersion

Example

mutation Cel(
  $id: String! = "uuid.New()" @cel
  $uppercase: String! = "strings.ToUpper(context.vars.lowercase)" @cel
  $expression: String! @cel
  $this: String! = "this.uppercase" @cel
  $nonCEL: String!
  $celNonCEL: String! = "this.nonCEL" @cel
) {
  evaluate(
    expressions: {
      a: "int(1)"
      b: "document.greeting + ' World!'"
      c: "decimal.Sub(decimal('1.234567'), decimal('0.987654321'))"
      d: "math.Max(double(123), double(456))"
      e: "size(string(document.uuid))"
      f: "document.upper"
      g: "document.expr"
      h: "document.this"
      i: "strings.ToUpper(document.celNonCEL)"
    }
    document: {
      greeting: "Hello"
      uuid: $id
      upper: $uppercase
      expr: $expression
      this: $this
      nonCEL: $nonCEL
      celNonCEL: $celNonCEL
    }
  )
}

events

Queries in the events namespace retrieve event data, such as webhooks.

createEndpoint

Create a new endpoint.

Resolves to

Endpoint!

Arguments

input - EndpointInput! Fields to create a new endpoint.

Example

mutation CreateEndpoint {
  events {
    createEndpoint(
      input: {
        endpointId: "345940ed-2726-4b20-88aa-820857ac0e68"
        status: ENABLED
        endpointType: WEBHOOK
        url: "https://webhook.site/twisp-webhook-test"
        description: "subscribe to balance and account events"
        subscription: ["balance*", "account.*"]
      }
    ) {
      endpointId
      status
      endpointType
      url
      subscription
      description
    }
  }
}

deleteEndpoint

Resolves to

Endpoint

Arguments

id - UUID! Unique identifier.

updateEndpoint

Update fields on an existing account. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Endpoint

Arguments

id - UUID! Unique identifier.
input - EndpointUpdateInput! Fields to update.

files

createDownload

Create a link to download a file.

Resolves to

Download

Arguments

key - String! The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.

createUpload

Create a file upload.

Resolves to

Upload

Arguments

input - CreateUpload!

postTransaction

Write a transaction to the ledger using the predefined defaults from the tranCode provided.

Resolves to

Transaction!

Arguments

input - TransactionInput! Fields to post a new Transaction.

Example

mutation PostTransaction(
  $accountCustomerAliciaId: UUID!
  $accountCustomerBobbyId: UUID!
) {
  postTransaction(
    input: {
      transactionId: "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68"
      tranCode: "BOOK_TRANSFER"
      params: {
        crAccount: $accountCustomerAliciaId
        drAccount: $accountCustomerBobbyId
        amount: "1.00"
        currency: "USD"
        effective: "2022-09-08"
      }
    }
  ) {
    transactionId
  }
}

removeFromAccountSet

Remove a member from a set.

Resolves to

AccountSet!

Arguments

id - UUID! Unique identifier for set.
member - AccountSetMemberInput! Account or AccountSet to add as a member of this set.

scheduler

Mutations in the scheduler namespace are used to manage scheduled jobs

createSchedule

Resolves to

Schedule

Arguments

input - CreateScheduleInput! Fields to create a new schedule.

schema

Mutations in the schema namespace are used to manage custom indexes, including historical indexes. Use the schema namespace to create and delete indexes.

createHistoricalIndex

Create a custom index for querying all versions of records' histories.

Because the Twisp FLDB is an immutable, append-only data store, changing the data within any record results in a new version of that record, leaving the original version intact in history.

While regular indexes (such as those created by the schema.createIndex mutation) will index the most recent version of records, a historical index will index every version. This allows for defining sophisticated indexes to enable queries such as:

  • Retrieving account balances when the balance amount was negative.
  • Finding records' state when a particular value is set in their metadata.
  • Pulling time-delimited sets of balance activity.

Partitions on historical indexes will by definition be larger than their equivalent partitions for regular indexes as they will contain not just the latest version of a record but also every previous version.

Resolves to

Index!

Arguments

createIndex

Create a custom index for querying records. Currently available for indexing Account, AccountSet, Balance, Entry, Transaction, and TranCode record types.

To query the index, use the CUSTOM index type for the applicable resource query and supply the filter inputs specified by the index.

Custom indexes can be created using fields on the root level of the record like Account.modified as well as nested fields within documents like the metadata object.

Depending on the parameters defined, custom indexes may be structured to return a single record or a sorted list of records.

Note that due to the scaling properties of the underlying database, a single partition supports a fixed amount of read bandwidth and individual write operations per second. Beyond that threshold, throttling will occur. Visit scaling properties for more information.

When designing custom indexes, care must be taken to ensure that reads and writes are spread across a sufficient number of partitions to support peak workloads. In practice, partitioning by account is usually sufficient. Our technical support staff is available for guidance on partition design patterns at support@twisp.com.

To learn more about indexes within the Twisp FLDB, see Index-First Design in the docs.

Resolves to

Index!

Arguments

Example

mutation SchemaCreateIndex {
  schema {
    createIndex(
      input: {
        name: "Transaction.metadata.category"
        on: Transaction
        unique: false
        partition: [
          { alias: "correlation_id", value: "document.correlation_id" }
        ]
        sort: [
          {
            alias: "category"
            value: "string(document.metadata.category)"
            sort: ASC
          }
        ]
        constraints: { hasCategory: "has(document.metadata.category)" }
      }
    ) {
      range {
        alias
        value
        sort
      }
      partition {
        alias
        value
      }
      on
      constraints
      unique
    }
  }
}

createSearchIndex

Create a search index for full text search support.

Full text search indexes are powered by opensearch. These indexes are eventually consistent, but have the ability to execute complex queries utilizing the opensearch indexing engine.

Resolves to

Index!

Arguments

deleteIndex

Delete an existing index.

Resolves to

Index

Arguments

name - String! The String scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.
on - IndexOnEnum! Record types which support custom indexes.

Example

mutation SchemaDeleteIndex {
  schema {
    deleteIndex(name: "Transaction.metadata.category", on: Transaction) {
      name
      on
    }
  }
}

updateAccount

Update fields on an existing account. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Account!

Arguments

id - UUID! Unique identifier.
input - AccountUpdateInput! Fields to update.

Example

mutation UpdateAccount($accountCardSettlementId: UUID!) {
  updateAccount(id: $accountCardSettlementId, input: { code: "CARD.SETTLE" }) {
    accountId
    code
    history(first: 2) {
      nodes {
        version
        code
      }
    }
  }
}

updateAccountSet

Update fields on an existing account set. To ensure data integrity, only a subset of fields are allowed.

Resolves to

AccountSet!

Arguments

id - UUID! Unique identifier.
input - AccountSetUpdateInput! Fields to update.

Example

mutation UpdateAccountSet($accountSetCustomersId: UUID!) {
  updateAccountSet(
    id: $accountSetCustomersId
    input: { name: "Customer Wallets" }
  ) {
    accountSetId
    name
    history(first: 2) {
      nodes {
        version
        name
      }
    }
  }
}

updateEntry

Update an existing ledger entry. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Entry!

Arguments

id - UUID! Unique identifier.
input - EntryUpdateInput! Entry fields to update.

updateJournal

Update an existing journal. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Journal!

Arguments

id - UUID! Unique identifier.
input - JournalUpdateInput! Journal fields to update.

Example

mutation UpdateJournal($journalGLId: UUID!) {
  updateJournal(
    id: $journalGLId
    input: { description: "_The_ ledger. The only one." }
  ) {
    journalId
    description
    history(first: 2) {
      nodes {
        version
        description
      }
    }
  }
}

updateTranCode

Update an existing tran code. To ensure data integrity, only a subset of fields are allowed.

Resolves to

TranCode!

Arguments

id - UUID! Unique identifier.
input - TranCodeUpdateInput! TranCode fields to update.

Example

mutation UpdateTranCode($tcBookTransferId: UUID!) {
  updateTranCode(
    id: $tcBookTransferId
    input: {
      description: "Book transfer between two customer wallet accounts."
      entries: [
        {
          accountId: "params.drAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_DR'"
          direction: "DEBIT"
          layer: "SETTLED"
          metadata: "{'first': 1}"
        }
        {
          accountId: "params.crAccount"
          units: "params.amount"
          currency: "params.currency"
          entryType: "'BOOK_TRANSFER_CR'"
          direction: "CREDIT"
          layer: "SETTLED"
          metadata: "{'second':2}"
        }
      ]
    }
  ) {
    tranCodeId
    description
    entries {
      metadata
    }
    history(first: 2) {
      nodes {
        version
        description
      }
    }
  }
}

updateTransaction

Update an existing transaction. To ensure data integrity, only a subset of fields are allowed.

Resolves to

Transaction!

Arguments

id - UUID! Unique identifier.
input - TransactionUpdateInput! Transaction fields to update.

Example

mutation UpdateTransaction {
  updateTransaction(
    id: "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68"
    input: { metadata: { reconciled: true } }
  ) {
    transactionId
    metadata
    history(first: 2) {
      nodes {
        version
        metadata
      }
    }
  }
}

voidTransaction

Void an existing transaction.

Resolves to

Transaction!

Arguments

id - UUID! Unique identifier.

Example

mutation VoidTransaction($transactionId: UUID!) {
  voidTransaction(id: $transactionId) {
    transactionId
    voidOf
  }
}

warehouse

Mutations in the warehouse namespace are used to manage the twisp data warehouse.

batchExecuteStatement

Resolves to

BatchExecuteStatementOutput

Arguments

cancelStatement

Resolves to

CancelStatementOutput

Arguments

executeStatement

Resolves to

ExecuteStatementOutput

Arguments

executeStatementSync

Resolves to

ExecuteStatementSyncOutput

Arguments

Example

mutation uuid_formatting {
  warehouse {
    executeStatementSync(
      input: {
        sql: "select accountid, from_varbyte(accountid, 'hex') as uuid from account_history limit 1"
      }
    ) {
      records {
        fields {
          value {
            str
          }
        }
      }
      columnMetadata {
        name
      }
    }
  }
}

workflow

Mutations in the workflow namespace are used to manage and execute workflows.

execute

Execute a workflow identified by workflowId.

Resolves to

JSON!

Arguments

input - WorkflowInput! Fields to execute a new workflow.

executeTask

Execution workflow identified by workflowId and executionId to the state identified by task.

Resolves to

WorkflowOutput!

Arguments

input - WorkflowInput! Fields to execute a new workflow.