# Configuration Reference for ACH configuration within the Twisp ACH Processor ## The Basics ACH configurations define the operational parameters for processing ACH transactions. Each configuration specifies the accounts, webhook endpoints, file header information, and timezone settings required for both originating (ODFI) and receiving (RDFI) ACH operations. Configurations in Twisp... - Connect settlement, suspense, exception, and fee accounts - Define ODFI header information for NACHA file generation - Reference webhook endpoints for transaction decisioning - Specify journal for posting all ACH transactions - Declare a direction (`RDFI`, `ODFI`, or `BOTH`) that restricts which file types the configuration may process - Optionally enable auto-pending mode, which receives RDFI entries without sending webhooks: forward entries post to a pending account, and matched dishonored returns and unmatched returns post there on the settled layer ## Components of ACH Configuration There are 7 primary components which define an ACH configuration: 1. **Accounts**: Settlement, suspense, and exception accounts are always required. The fee account is required unless the configuration is RDFI-only. Auto-pending configurations additionally require a pending account. 2. **Webhook Endpoint**: Receives decisioning requests during file processing, allowing custom business logic for transaction acceptance or rejection. It is optional and unused when auto-pending is enabled. 3. **ODFI Header Configuration**: Company and bank information used when generating NACHA-formatted files for transmission. 4. **Journal**: The ledger journal where all ACH transaction entries are posted. 5. **Timezone**: IANA timezone identifier for date/time operations and effective date calculations. 6. **Direction**: Whether the configuration processes `RDFI` files, `ODFI` files, or `BOTH` (the default). 7. **Auto Pending**: When enabled, RDFI processing sends no webhooks. Forward entries post as pending to the configured pending account, and matched dishonored returns and unmatched returns post there on the settled layer. Optional components may also be configured: - **Trace Number Configuration**: A reserved range of trace numbers Twisp generates from when originating files. - **File Modifier Configuration**: A reserved range of file ID modifiers Twisp assigns to the files it generates each day, or an instruction to take the modifier from the caller instead. In addition, configurations have common properties: - **Config ID**: a universally unique identifier (UUID) for the configuration. - **Version**: configurations are versioned, allowing tracking of changes over time and ensuring file processing references the correct configuration version. - **Created & Modified Timestamps**: when the configuration was created and last updated. ## Required Accounts ### Settlement Account The settlement account is the central hub for ACH fund flows. All incoming and outgoing ACH transactions post to this account during processing phases. **Characteristics:** - Normal balance type: DEBIT (typically holds positive balance from incoming credits) - `enableConcurrentPosting: true` (supports high transaction volumes) - Debited for ODFI PULL transactions, credited for ODFI PUSH transactions - Credited for RDFI inbound credits, debited for RDFI inbound debits ### Suspense Account Suspense account receives transactions where the destination account cannot be located, commonly when routing number and account number combinations don't match existing accounts. **Characteristics:** - `enableConcurrentPosting: true` (may receive high transaction volumes) - Requires manual review to determine correct account or return to originator - Funds held pending investigation or return processing ### Exception Account The exception account receives transactions that cannot be applied automatically. This includes transactions that fail processing due to velocity controls, locked accounts, or other business rule violations. It also receives unmatched inbound returns unless auto-pending is enabled, in which case their initial posting uses the pending account. A return is unmatched when its trace has no eligible workflow to answer. **Characteristics:** - `enableConcurrentPosting: true` (supports parallel processing) - Unmatched returns post with transaction code `SYS_ACH_UNKNOWN_RETURN_CR` or `SYS_ACH_UNKNOWN_RETURN_DR`, based on the return entry's transaction code - Newly processed unmatched regular, dishonored, and contested returns expose an `ACH_RDFI_UNMATCHED_RETURN` execution; auto-pending uses the pending account for CREATE, while other configurations use the exception account - Processing an unmatched return sets `hasExceptions` on the inbound file - The transaction and entry metadata contain the parsed RDFI workflow entry for investigation - Requires manual review to return rejected forward entries or reconcile unmatched inbound returns held in this account ### Fee Account Fee account collects ACH processing fees charged per transaction. It is required unless the configuration's direction is `RDFI` (fees are only charged on ODFI operations). **Characteristics:** - Normal balance type: CREDIT (accumulates fee income) - `enableConcurrentPosting: true` (supports high transaction volumes) - Credited when fees charged, debited when fees reimbursed (on returns/cancellations) ### Pending Account (auto-pending only) The pending account receives every forward RDFI entry, the settled posting for every matched dishonored return, and the initial posting for every unmatched return when the configuration has auto-pending enabled. It is required when `autoPending: true` and unused otherwise. **Characteristics:** - Holds encumbered forward-entry funds awaiting resolution and settled return postings awaiting reconciliation - `enableConcurrentPosting: true` recommended (receives every forward entry plus matched dishonored and unmatched returns) - See [Auto Pending Mode](https://www.twisp.com/docs/reference/ach/configuration.md#auto-pending-mode) below ## Direction The `direction` field declares which side of ACH processing a configuration handles: - `BOTH` (default): Processes RDFI and ODFI files. Existing configurations created before this field existed behave as `BOTH`. - `RDFI`: Receives incoming files only. [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file) rejects ODFI file types (`ODFI_RETURN`, `ODFI_PREPROCESS_RETURN`, `ODFI_PROCESSED`) with a `BadRequest`. The fee account becomes optional. - `ODFI`: Originates outgoing files only. `processFile` rejects RDFI file types. Auto-pending cannot be enabled. ## Auto Pending Mode Auto-pending is a hands-off RDFI ingest mode. When `autoPending: true`, RDFI processing sends no webhooks. Forward entries are automatically posted as `PENDING` to the configured pending account, where they wait for you to settle or return them. Matched dishonored returns and unmatched-return CREATE transactions post to the same account on the settled layer. **Requirements:** - `pendingAccountId` is required, must reference an existing account, and must differ from the settlement, suspense, and exception accounts - `direction` must be `RDFI` or `BOTH` — enabling auto-pending on an `ODFI` configuration is a validation error - `endpointId` becomes optional. Auto-pending sends no webhooks, even when an endpoint is configured. **Behavior:** - Forward entries post to the pending account's encumbrance layer, exactly as if a decisioning webhook had responded `PENDING` with that account - A matched dishonored return posts on the pending account's settled layer and remains at `DISHONOR` until you move or contest it with `workflow.executeTask` - An unmatched return posts on the pending account's settled layer and exposes an `ACH_RDFI_UNMATCHED_RETURN` execution for correction or any available reply - The file transitions `PROCESSING → PENDING` and remains there until every forward entry reaches a terminal state, then transitions to `COMPLETED` (it skips `PROCESSED`, since no webhooks are ever sent) - Resolve each forward entry by executing a `SETTLE` or `RETURN` task on its workflow execution, the same as resolving a webhook-pended entry See the [RDFI reference](https://www.twisp.com/docs/reference/ach/rdfi.md#auto-pending-mode) for the end-to-end flow. ## ODFI Header Configuration ODFI header configuration contains NACHA file header information required when generating ACH files. **Components:** - **Immediate Destination**: Routing number of receiving institution (ODFI or Federal Reserve) - **Immediate Destination Name**: Name of receiving institution (max 23 characters) - **Immediate Origin**: Your Federal Tax ID or routing number (10 characters) - **Immediate Origin Name**: Your company name as it appears in ACH files (max 23 characters) These values populate the File Header Record (Record Type Code 1) in generated NACHA files. ## Webhook Endpoint The webhook endpoint receives POST requests during ACH file processing for transaction decisioning. The endpoint must be of type `ACH_PROCESSOR`. It is required unless the configuration has [auto-pending](https://www.twisp.com/docs/reference/ach/configuration.md#auto-pending-mode) enabled, and it is not used at all while auto-pending is enabled. **Request Format:** Webhook receives transaction details including amount, account identifiers, and entry metadata when processing files via [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file). **Response Format:** Webhook responds with settlement instructions specifying which account to credit/debit, or directing transaction to suspense/exception accounts. **Timeout:** Webhook must respond within configured timeout period to avoid transaction failure. See the [RDFI reference](https://www.twisp.com/docs/reference/ach/rdfi.md#4-handle-transaction-webhooks) for detailed webhook payload and response specifications. ## Timezone IANA timezone identifier determines date/time interpretation for: - Effective dates for ACH transactions - Settlement window calculations - Batch header dates in NACHA files - Processing cutoff time interpretation Common values: `America/New_York`, `America/Chicago`, `America/Denver`, `America/Los_Angeles`, `America/Phoenix` Use the timezone where primary ACH operations occur, typically matching ODFI timezone or business headquarters location. ## Trace Number Configuration Every entry in a NACHA file carries a 15-character trace number: an 8-character ODFI routing prefix followed by a 7-digit sequence number. Twisp assigns the sequence number whenever it originates a file — including return and NOC (notification of change) files generated for RDFI operations. If your program originates its own forward files outside of Twisp, those files draw sequence numbers from the same 7-digit space, and trace numbers could collide with the ones Twisp generates. To prevent this, reserve a block of trace numbers for Twisp: - **Min Trace Number**: The lowest sequence number Twisp will generate. Must be greater than or equal to 1. - **Max Trace Number**: The highest sequence number Twisp will generate. Must be greater than the min and less than or equal to 9999999. When configured, all trace numbers Twisp generates for this configuration fall within the reserved range, wrapping back to the min after the max is used. When omitted, Twisp generates from the full range of 1 to 9999999. **Range size and file generation:** - Return and NOC files contain at most as many entries as the range holds. If more entries are queued than fit, the file is generated with a full range of entries and the remainder automatically carries over to the next file generation. - Twisp-originated forward files fail with an error if a single file would contain more entries than the range holds. Size the reserved range comfortably above your expected per-file entry counts. The trace number configuration can be set at creation via [`Mutation.ach.createConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.create-configuration) or added later via [`Mutation.ach.updateConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.update-configuration). If the range is changed while the current trace position lies outside the new range, generation restarts from the new min. ## File Modifier Configuration Every NACHA file header carries a single-character file ID modifier that distinguishes files created on the same day with the same origin and destination. Modifiers must be unique per day, so Twisp records the ones each day has used (in the configuration's timezone) and assigns each file the first modifier of the sequence `A` through `Z`, then `0` through `9`, that the day has not used yet. The first file of a day therefore takes `A`, and generation fails once the day has used every modifier of the sequence. If your program originates files outside of Twisp with the same origin and destination, those files draw modifiers from the same per-day space and could collide with the ones Twisp assigns. The file modifier configuration prevents this in one of two ways: reserve a range of modifiers for Twisp, or supply the modifier of each file yourself. The configuration can be set at creation via [`Mutation.ach.createConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.create-configuration) or added later via [`Mutation.ach.updateConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.update-configuration). Set a range or `userSupplied`, never both. Configuring the full range — start `A`, end `9` — resets the configuration to Twisp's default: it is stored as no file modifier configuration at all, which is how a range or `userSupplied` is cleared once set. ### Reserved Range - **Start File ID Modifier**: The first modifier Twisp assigns each day. A single character from `A-Z` or `0-9`. - **End File ID Modifier**: The last modifier Twisp assigns each day. Must not come before the start in the sequence `A-Z` then `0-9`. A range with the same start and end reserves a single modifier, which allows one file per day. When configured, each file takes the first modifier of the range the day has not used yet. The first file of the day therefore takes the start modifier, and generation fails once the range holds no unused modifier. When omitted, Twisp assigns from the full sequence of `A` through `9` — up to 36 files per day. The range may be changed during the day. Twisp tracks the modifiers the day has already used rather than a position in the sequence, so a moved range picks up its first unused modifier and never reissues one. A range narrowed and widened again the same day fills the gaps it left behind, which can hand out a modifier below the day's last one. ### Caller-Supplied Modifiers Set **User Supplied** (`userSupplied: true`) to assign the modifier of every file yourself. Twisp then assigns no modifiers of its own, and `options.fileModifier` becomes a required argument of [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file). Generation fails with a bad request error when the modifier is missing, when it is not a single character from `A-Z` or `0-9`, or when a modifier is supplied to a configuration that reserves a range instead. Use this when the modifier of each file has to match an assignment your own systems already make. Twisp writes the supplied character to the file header as given, and enforces no sequence of its own: any unused modifier is accepted, in any order. See [Supplying the File ID Modifier](https://www.twisp.com/docs/reference/ach/odfi.md#supplying-the-file-id-modifier) for the generation option. Modifiers stay unique per day whoever chooses them. Supplied modifiers join the day's used modifiers, so a modifier the day has already written to a file is refused rather than reissued, and the two modes are safe to alternate: a configuration switched between `userSupplied` and a reserved range on the same day never repeats a modifier in either direction. Generation is not a repeatable operation — it drains the queued entries into the file it creates — so a refused repeat costs you nothing: the file that already carries the modifier remains available from [File Download](https://www.twisp.com/docs/reference/ach/file-operations.md#file-download). ## Offset Configuration (Balanced Files) By default, Twisp originates **unbalanced** files: batches contain only the forward entries, so the file's total credits and total debits differ. Some ODFIs require **balanced** files, where each batch carries an offset entry drawn on the originator's settlement account at the ODFI so credits equal debits. Setting `offsetConfiguration` opts a configuration into balanced origination files: - **Account Number**: The account offset entries are drawn on (required, max 17 characters). - **Account Type**: `CHECKING` or `SAVINGS` (required). - **Routing Number**: The routing number offset entries are drawn on. When omitted, offsets are drawn on the configuration's Immediate Origin, which must then be a valid ABA routing number. - **Description**: Optional discretionary data carried on offset entries (max 2 characters). - **Enable Balanced Return/NOCs** (`enableBalancedReturnNOCs`): When true, generated return and NOC files are balanced as well. Defaults to false — only originated forward files are balanced. **Balanced forward file behavior:** - Each batch in a generated forward file ends with a single offset entry whose amount equals the sum of the batch's entries, posted with the opposite transaction code and the individual name `OFFSET`. - Batches with offsets use service class code 200 (mixed debits and credits), and file/batch control totals include the offset amounts — total credits always equal total debits. - Forward entries may not use the individual name `OFFSET`; it is reserved for generated offset entries. **Balanced return/NOC file behavior** (when `enableBalancedReturnNOCs` is set): - Return batches cannot carry a forward offset entry directly (NACHA parsers reject forward entries mixed into a return batch), so the offsets are collected into a single trailing forward batch — service class code 200, company entry description `OFFSET` — holding one offset entry per unbalanced batch. File control totals balance; individual return batches are unchanged. - NOC entries carry zero amounts, so NOC batches need no offset and are untouched; a pure NOC file has no offset batch. **Shared behavior:** - Offset entries consume trace numbers from the same sequence as regular entries, reserved exactly — one per offset entry, determined after batch consolidation — so the sequence carries no gaps. All trace numbers within a file must be distinct, so a [reserved trace range](https://www.twisp.com/docs/reference/ach/configuration.md#trace-number-configuration) must hold the file's entries plus its offset entries; return files cap their entry count at half the range so the worst case always fits. - Offsets only affect generated files. Ledger postings are unchanged: settlement is already modeled by the configuration's settlement account. Forward-file offsets apply to configurations with direction `ODFI` or `BOTH`; an RDFI-only configuration may use `offsetConfiguration` when `enableBalancedReturnNOCs` is set, since it generates only return and NOC files. Remove the configuration by passing `clearOffsetConfiguration: true` to [`Mutation.ach.updateConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.update-configuration). ## Configuration Versioning Configurations use optimistic locking with version numbers. Each update via [`Mutation.ach.updateConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.update-configuration) increments the version field. File processing records reference the specific configuration version used, ensuring immutability and audit trail consistency. When files are processed via [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file), the `configVersion` field on `AchFileInfo` captures which configuration version applied, allowing historical analysis even after configuration updates. ## Configuration Operations Use GraphQL to create, update, and query ACH configurations: - [`Mutation.ach.createConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.create-configuration): Create new ACH configuration. - [`Mutation.ach.updateConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.update-configuration): Update existing configuration fields. - [`Query.ach.configuration()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.configuration): Get a single configuration by ID. - [`Query.ach.configurations()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.configurations): List all configurations with pagination. ## Further Reading To learn how to set up ACH configuration from scratch, see the tutorial on [Setting Up ACH Processing](https://www.twisp.com/docs/tutorials/ach/setting-up-ach.md). For step-by-step configuration with real APIs, see the how-to guide on [Processing ACH Payments](https://www.twisp.com/docs/guides/processing-ach-payments.md). For complete GraphQL type definitions, see: - [AchConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) - [AchOdfiHeaderConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-odfi-header-configuration) - [AchTraceNumberConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-trace-number-configuration) - [AchFileModifierConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-modifier-configuration) - [AchOffsetConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-offset-configuration) - [AchCreateConfigurationInput](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-create-configuration-input) - [AchUpdateConfigurationInput](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-update-configuration-input) --- # File Operations Reference for ACH file processing within the Twisp ACH Processor ## Overview ACH file operations handle the complete lifecycle of NACHA-formatted files within the Twisp platform. This reference describes how Twisp processes ACH files: from upload and validation through parallel processing and generation. Understanding these internals helps you optimize file processing, debug issues, and integrate effectively with the ACH system. The Twisp ACH file processor: - Validates NACHA file format compliance with detailed error reporting - Partitions files for parallel transaction processing - Generates NACHA-compliant files from workflow transactions - Provides presigned URLs for secure file upload and download with expiration - Tracks file processing through multiple states with real-time statistics - Maintains complete file processing history and audit trails - Stores files in S3 with retention policies and versioning ## Components of File Operations There are 4 primary components in ACH file processing: 1. **File Upload**: Create presigned URLs for secure file uploads, supporting ACH and bulk GraphQL variable files. 2. **File Processing**: Parse NACHA files, validate format compliance, extract transactions, and route forward entries, returns, and NOCs. 3. **File Generation**: Create NACHA-formatted files from submitted transactions, ready for transmission to financial institutions. 4. **File Download**: Generate presigned URLs for secure file downloads with automatic expiration. In addition, file records maintain: - **File ID**: UUID derived from file key for tracking specific file processing instances. - **Processing Status**: Current state (NEW, VALIDATING, PROCESSING, PENDING, COMPLETED, ERROR, etc.). - **Processing Statistics**: Entry counts, credit/debit totals, unprocessed entry counts. - **Exception Indicator**: Whether the file contains unmatched regular, dishonored, or contested returns. - **Configuration Version**: Which ACH configuration version was used for processing. - **History**: Complete audit trail of all status changes and statistic updates. ## File Upload File upload uses a two-step process: first create a presigned URL, then upload file content via HTTP PUT. **Upload Types:** - `ACH`: NACHA-formatted text files for transaction processing - `BULK_GRAPHQL_VARIABLES`: JSON arrays for bulk GraphQL query execution **File Requirements for ACH:** - Content type: `text/plain` - Format: NACHA (National Automated Clearing House Association) standard - Character encoding: ASCII - Line endings: CRLF or LF - Record length: 94 characters per line Presigned upload URLs expire after a configured period. If expiration occurs before upload completes, create a new upload request. ## File Processing File processing parses uploaded NACHA files, validates format compliance, and extracts transaction details for decisioning. **File Types:** RDFI (Receiving): - `RDFI`: Incoming forward entries, returns for transactions you originated, and NOCs - `RDFI_RETURN`: Outbound return file generated for RDFI transactions you received - `RDFI_NOC`: Outbound Notification of Change file generated for RDFI transactions you received ODFI (Originating): - `ODFI`: Outgoing file with both PUSH and PULL transactions - `ODFI_PULL_ONLY`: Outgoing file with only PULL (debit) transactions - `ODFI_PUSH_ONLY`: Outgoing file with only PUSH (credit) transactions - `ODFI_RETURN`: Inbound return-only file for transactions you originated - `ODFI_PREPROCESS_RETURN`: Pre-process return file before final generation - `ODFI_PROCESSED`: Already processed ODFI file for reconciliation **Processing Phases:** 1. **Validation**: Verify NACHA format compliance, record structure, control totals 2. **Partitioning**: Split file for parallel transaction processing 3. **Entry Processing**: Route returns and NOCs, and send forward entries to the configured webhook endpoint (webhooks are skipped for [auto-pending configurations](https://www.twisp.com/docs/reference/ach/configuration.md#auto-pending-mode), which post every forward entry to the pending account instead) 4. **Settlement**: Apply settlement instructions from webhook responses 5. **Completion**: Mark all transactions settled or queued for returns The file type must match the configuration's [direction](https://www.twisp.com/docs/reference/ach/configuration.md#direction): an `RDFI`-only configuration rejects ODFI file types and vice versa. `BOTH` (the default) accepts every file type. **Preprocessing Options:** When using `ODFI_PREPROCESS_RETURN` file type, specify output file keys for filtered results: - `preprocessedFileKey`: Entries passing preprocessing rules - `preprocessedExcludedFileKey`: Entries failing preprocessing rules ## File Generation File generation creates NACHA-formatted files from submitted workflow transactions. **Generation Options:** - `generateEmpty: true`: Always create file, even without transactions (empty NACHA with headers) - `generateEmpty: false`: Only create file if transactions exist (returns `generated: false` if none) - `options.fileHeaderReferenceCode`: Optional value for the file header's Reference Code field (positions 87-94). Up to 8 printable ASCII characters, with no leading or trailing spaces; space-filled when omitted. See [ODFI File Generation](https://www.twisp.com/docs/reference/ach/odfi.md#generating-files) for details. - `options.fileModifier`: File ID modifier for the file header (position 34). A single character from `A-Z` or `0-9` that the day has not used yet — a repeat is refused. Required when the configuration sets `userSupplied` on its [File Modifier Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#file-modifier-configuration), and rejected otherwise. See [Supplying the File ID Modifier](https://www.twisp.com/docs/reference/ach/odfi.md#supplying-the-file-id-modifier) for details. **File Type Selection:** Use separate file types when: - ODFI requires distinct files for credits vs debits - Different transmission schedules for transaction types - Risk management requires transaction type isolation - Separate approval workflows needed Use combined `ODFI` file type when: - Processing both credits and debits together - Single transmission window - Financial institution accepts mixed transaction files Generated files are NACHA-compliant and ready for transmission via SFTP, FTPS, or other secure transfer methods. ## File Download File download provides presigned URLs for retrieving generated or processed files. **Download Process:** 1. Request download URL via GraphQL mutation 2. Receive presigned URL with expiration timestamp 3. Download file content via HTTP GET before expiration Presigned download URLs expire after configured period. If URL expires, create new download request with same file key. ## File Lifecycle Deep Dive Understanding how Twisp processes ACH files helps you optimize integration, debug issues, and monitor progress effectively. ### Processing Phases File processing progresses through multiple phases, each with specific responsibilities and state transitions. #### Phase 1: Upload (NEW → UPLOADED) **NEW State:** - File record created via [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file) - File ID generated from file key - Initial `AchFileInfo` record stored with configuration version - Processing status set to `NEW` **UPLOADED State:** - File content uploaded to S3 via presigned URL from [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-upload) - System detects uploaded file and transitions to `UPLOADED` - File queued for validation - Processing statistics initialized to zero **Transition Trigger:** S3 upload completion detected by file processor #### Phase 2: Validation (UPLOADED → VALIDATING → PARTITIONING) **VALIDATING State:** - Parser reads NACHA file structure - Validates file header record (Record Type 1) - Validates batch header records (Record Type 5) - Validates entry detail records (Record Type 6) - Validates addenda records (Record Type 7) - Validates control records (Record Types 8, 9) - Checks hash totals and entry counts - Verifies record length (94 characters) **Validation Checks:** - File header immediate destination/origin format - Batch header service class codes - Entry detail transaction codes - Routing number check digit validation - Control total reconciliation - Record sequence validation **On Success:** Transitions to `PARTITIONING` **On Failure:** Transitions to `INVALID` with detailed error in `processingDetail` #### Phase 3: Partitioning (PARTITIONING → PROCESSING) **PARTITIONING State:** - File split into partitions for parallel processing - Each partition contains subset of entry detail records - Partition size optimized for concurrent webhook processing - Entry record IDs and trace numbers retained for workflow and return matching **Partitioning Strategy:** - Default: 100 entries per partition - Configurable based on expected webhook latency - Partitions processed independently by worker pool - Enables horizontal scaling of webhook processing **Transition Trigger:** All partitions created and queued #### Phase 4: Entry Processing (PROCESSING → PROCESSED) **PROCESSING State (RDFI only):** - Forward entries trigger webhooks to the configured endpoint - Matched regular returns execute `RETURN` on their original ODFI workflows - Unmatched regular, dishonored, and contested returns create `ACH_RDFI_UNMATCHED_RETURN` executions, post to the pending account in auto-pending mode or the exception account otherwise, and set `hasExceptions` on the file - NOCs and refused NOCs are skipped without ledger activity or webhook delivery - Webhooks sent in parallel across partitions - Forward-entry responses collected: `SETTLE`, `PENDING`, `RETURN`, or `RETRY` - Statistics updated: `numEntriesUnprocessed` decrements - Retry logic for failed webhooks (exponential backoff) **Auto-Pending Files (RDFI):** - No webhooks are sent — every entry posts as `PENDING` to the configured pending account - The file transitions `PROCESSING → PENDING` once all entries are posted - The file holds in `PENDING` until every entry is manually settled or returned, then transitions directly to `COMPLETED` (skipping `PROCESSED`) **ODFI Files:** - ODFI files skip webhook processing - Transition directly to `PROCESSED` after partitioning **Monitoring:** Query `processingStatistics.numEntriesUnprocessed` via [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file) to track progress: ```graphql query MonitorFileProcessing { ach { file(fileKey: "incoming-20251114.ach", configId: "config-001") { processingStatus hasExceptions processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } } } } ``` **Transition Trigger:** `numEntriesUnprocessed` reaches zero #### Phase 5: Settlement (PROCESSED → COMPLETED) **PROCESSED State:** - All entries routed and all forward-entry webhook responses received - Transactions awaiting settlement based on effective dates - For RDFI: Settlement occurs when workflow SETTLE state executes - For ODFI: Settlement occurs immediately after file generation - Entries you pended via a `PENDING` webhook response do not block this state, but hold the file here until you settle or return them **PENDING State (auto-pending files only):** - Every entry posted to the configured pending account, no webhooks sent - Entries await manual `SETTLE` or `RETURN` via their workflow executions - File transitions directly to `COMPLETED` once all entries resolve **COMPLETED State:** - All transactions settled or queued for returns - File processing complete - Final statistics recorded - File available for download **Transition Trigger:** All transactions reach terminal state (settled or returned) ### State Transition Diagram ``` ┌─────────┐ │ NEW │ File record created └────┬────┘ │ File uploaded ↓ ┌─────────┐ │UPLOADED │ File content in S3 └────┬────┘ │ Validation starts ↓ ┌──────────┐ Validation fails ┌─────────┐ │VALIDATING├────────────────────────→│ INVALID │ Terminal └────┬─────┘ └─────────┘ │ Validation succeeds ↓ ┌─────────────┐ Processing error ┌────────┐ │PARTITIONING ├──────────────────────→│ ERROR │ Terminal └──────┬──────┘ └────────┘ │ Partitions created ↓ ┌────────────┐ Manual abort ┌─────────┐ │ PROCESSING ├───────────────────────→│ ABORTED │ Terminal └──────┬─────┘ └─────────┘ │ │ All entries processed Auto-pending: all entries │ posted to pending account ├──────────────────────────────────┐ ↓ ↓ ┌───────────┐ ┌─────────┐ │ PROCESSED │ Awaiting settlements │ PENDING │ Awaiting manual └─────┬─────┘ └────┬────┘ settle/return │ All settled/returned │ All settled/returned ↓ │ ┌───────────┐ │ │ COMPLETED │ Terminal ←──────────────────┘ └───────────┘ ``` ### Processing Status Reference | Status | Description | Next States | Typical Duration | |--------|-------------|-------------|------------------| | `NEW` | File record created | `UPLOADED`, `ERROR` | < 1 second | | `UPLOADED` | File in S3, queued | `VALIDATING` | < 5 seconds | | `VALIDATING` | Format validation | `PARTITIONING`, `INVALID` | 5-30 seconds | | `PARTITIONING` | Creating partitions | `PROCESSING`, `ERROR` | 5-15 seconds | | `PROCESSING` | Routing entries and sending forward-entry webhooks (auto-pending: posting entries) | `PROCESSED`, `PENDING`, `ABORTED` | Minutes to hours* | | `PROCESSED` | Entry processing complete | `COMPLETED` | Hours to days** | | `PENDING` | Auto-pending entries await manual settle/return | `COMPLETED` | Hours to days** | | `COMPLETED` | Final state | None | Permanent | | `INVALID` | Validation failed | None | Permanent | | `ERROR` | Processing error | None | Permanent | | `ABORTED` | Manually stopped | None | Permanent | \* Depends on webhook response time and retry logic \** Depends on transaction effective dates, settlement timing, and manual resolution of pended entries ## Processing Statistics Processing statistics track entry counts and monetary totals during file processing. **Statistics Fields:** - `numEntriesUnprocessed`: Entries awaiting webhook responses - `totalCreditAmount`: Sum of all credit transactions (in cents) - `totalDebitAmount`: Sum of all debit transactions (in cents) Statistics update throughout processing lifecycle, providing real-time visibility into file processing progress. ## File Format Validation Twisp validates NACHA file format compliance during the `VALIDATING` phase. Understanding validation helps you debug file issues and ensure compliance. ### What Twisp Validates **File Structure:** - Record length: Every line must be exactly 94 characters - Record types: Must be 1, 5, 6, 7, 8, or 9 - Record sequence: File Header → Batch(es) → File Control - Line endings: CRLF or LF accepted - Character encoding: ASCII only **File Header Record (Type 1):** - Immediate destination: 10 characters (routing number or " ") - Immediate origin: 10 characters (Tax ID or routing number) - File creation date/time: Valid YYMMDD and HHMM - File ID modifier: Single character A-Z or 0-9 **Batch Header Record (Type 5):** - Service class code: 200 (mixed), 220 (credits), 225 (debits) - Company identification: 10 characters - Standard entry class code: Valid SEC code (PPD, CCD, WEB, etc.) - Effective entry date: Valid YYMMDD format - Originator status code: 0, 1, or 2 - ODFI identification: 8-digit routing number **Entry Detail Record (Type 6):** - Transaction code: Valid code (22, 23, 24, 27, 28, 29, 32, 33, 34, 37, 38, 39) - Receiving DFI identification: 8 digits - Check digit: Matches routing number check digit algorithm - DFI account number: 1-17 characters - Amount: 10-digit number (cents) - Trace number: 15 digits (ODFI routing + sequence) **Batch Control Record (Type 8):** - Entry count matches actual entries in batch - Entry hash matches sum of RDFI routing numbers (rightmost 10 digits) - Total debit amount matches sum of debit entries - Total credit amount matches sum of credit entries **File Control Record (Type 9):** - Batch count matches actual batches - Block count correct (records / 10, rounded up) - Entry and addenda count matches total - Entry hash matches sum of all RDFI routing numbers - Total debit/credit amounts match sums across all batches ### Common Validation Errors **Record Length Errors:** ``` Error: "Line 15: Record length is 93, expected 94" Fix: Ensure all lines are exactly 94 characters (pad with spaces if needed) ``` **Check Digit Errors:** ``` Error: "Line 42: Check digit 7 does not match calculated value 3" Fix: Recalculate check digit using ABA routing number algorithm ``` **Control Total Mismatch:** ``` Error: "Batch 1: Entry count 150 does not match control record value 148" Fix: Verify all entries included in batch, regenerate control record ``` **Invalid Transaction Code:** ``` Error: "Line 67: Invalid transaction code 21" Fix: Use valid codes (22-29 for checking, 32-39 for savings) ``` **Entry Hash Mismatch:** ``` Error: "File Control: Entry hash 1234567890 does not match calculated 1234567891" Fix: Sum first 8 digits of all RDFI routing numbers, take rightmost 10 digits ``` ### Debugging Validation Failures When a file fails validation (status `INVALID`), check `processingDetail` for error information: ```graphql query GetValidationError { ach { file(fileKey: "problematic-file.ach", configId: "config-001") { fileId processingStatus processingDetail modified } } } ``` **Example `processingDetail` values:** - `"Line 42: Record length is 93, expected 94"` - `"Batch 1: Entry count mismatch (expected 150, got 148)"` - `"File Control: Total debit amount mismatch"` ### Validation Best Practices **Before Uploading:** - Use NACHA file validation tools - Verify record lengths (94 characters exactly) - Check control totals match entry counts - Validate routing number check digits - Ensure valid transaction codes for account types **After Validation Errors:** - Read `processingDetail` for specific line/field errors - Fix source data or file generation logic - Re-upload corrected file with new file key - Consider automated pre-validation before Twisp upload ## Parallel Processing Architecture Twisp partitions large ACH files for concurrent webhook processing, enabling high-throughput file processing. ### How Partitioning Works **Partition Creation (PARTITIONING state):** 1. File parsed and validated 2. Entry detail records extracted 3. Entries divided into partitions (default 100 per partition) 4. Each partition assigned to worker in pool 5. Workers process partitions concurrently **Partition Processing:** - Each worker processes its partition independently - Webhooks sent in parallel across all workers - No cross-partition dependencies - Failures in one partition don't affect others **Concurrency Model:** ``` File: 1,000 entries ├── Partition 1: Entries 1-100 → Worker 1 ├── Partition 2: Entries 101-200 → Worker 2 ├── Partition 3: Entries 201-300 → Worker 3 ├── ... └── Partition 10: Entries 901-1000 → Worker 10 Each worker sends 100 webhooks in parallel Total: 1,000 webhooks sent concurrently across 10 workers ``` ### Performance Characteristics **Throughput:** - Small files (< 100 entries): 30-60 seconds total - Medium files (100-1,000 entries): 2-5 minutes with fast webhooks - Large files (1,000-10,000 entries): 10-30 minutes with fast webhooks - Very large files (> 10,000 entries): Linear scaling with partition count **Bottlenecks:** - Webhook response time (primary factor) - Webhook endpoint throughput - Database transaction commit latency - Network bandwidth for webhook traffic **Optimization Tips:** - Optimize webhook endpoint for < 100ms response time - Use async processing in webhook handler - Enable connection pooling for database access - Consider horizontal scaling of webhook endpoint - Monitor `numEntriesUnprocessed` to track progress ### Monitoring Parallel Processing Track processing progress in real-time via [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file): ```graphql query MonitorProcessing { ach { file(fileKey: "large-file.ach", configId: "config-001") { processingStatus processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } modified } } } ``` Poll every 5-10 seconds during `PROCESSING` state to track `numEntriesUnprocessed` countdown. ## Storage and Retention Twisp stores ACH files in AWS S3 with security, retention, and versioning policies. ### File Storage Location **S3 Bucket Structure:** ``` twisp-ach-files-{region}/ ├── uploads/ │ ├── {tenantId}/ │ │ └── {fileKey} ├── generated/ │ ├── {tenantId}/ │ │ └── {fileKey} └── archived/ ├── {tenantId}/ └── {fileKey} ``` **Storage Classes:** - Uploads: Standard S3 (frequent access) - Generated files: Standard S3 (frequent access for 30 days) - Archived files: Glacier after 90 days (compliance retention) ### Retention Policies **Upload Files:** - Retained for 90 days after upload - Archived to Glacier for 7 years (NACHA compliance) - Accessible via file key throughout retention period **Generated Files:** - Retained for 90 days in Standard S3 - Archived to Glacier for 7 years - Download URLs valid for 15 minutes (renewable) **File Metadata:** - `AchFileInfo` records retained permanently - Processing history retained for audit trail - Statistics snapshots retained at each version - Enables compliance reporting and reconciliation ### Versioning **File Versioning:** - S3 versioning enabled on ACH file buckets - Protects against accidental deletion - Enables recovery of overwritten files - Version history retained for full retention period **Metadata Versioning:** - `AchFileInfo.version` increments on each update - `AchFileInfo.history` connection provides all versions - Each version captures processing state snapshot - Enables point-in-time analysis ### Security **Encryption:** - S3 server-side encryption (SSE-S3) enabled - Files encrypted at rest - Presigned URLs use HTTPS only - API access requires authentication **Access Control:** - Tenant-isolated S3 paths - IAM roles restrict cross-tenant access - Presigned URLs scoped to specific file key - Time-limited URLs (15-minute expiration) ## Upload and Download Mechanics Twisp uses presigned URLs for secure, direct S3 access without exposing AWS credentials. ### Upload Process **Step 1: Create Upload URL** Call [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-upload) to get presigned URL: ```graphql mutation CreateUpload { files { createUpload( input: { key: "incoming-20251114.ach" uploadType: ACH contentType: "text/plain" } ) { uploadURL } } } ``` **Response:** ```json { "files": { "createUpload": { "uploadURL": "https://s3.amazonaws.com/twisp-ach-files/.../incoming-20251114.ach?X-Amz-..." } } } ``` **Step 2: Upload File Content** Use HTTP PUT to upload file to presigned URL: ```bash curl -T incoming-20251114.ach \ -H "Content-Type: text/plain" \ -XPUT '' ``` **Important:** - URL expires after 15 minutes - Content-Type must match specified type - Maximum file size: 100 MB - Upload must complete before expiration **Step 3: Process File** After upload completes, start processing with [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file): ```graphql mutation ProcessFile { ach { processFile( input: { configId: "config-001" fileKey: "incoming-20251114.ach" fileType: RDFI } ) { fileId } } } ``` ### Download Process **Step 1: Generate Download URL** Call [`Mutation.files.createDownload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-download) to get presigned URL: ```graphql mutation CreateDownload { files { createDownload( key: "outgoing-20251114.ach" ) { downloadURL } } } ``` **Step 2: Download File Content** Use HTTP GET to download file from presigned URL: ```bash curl '' -o outgoing-20251114.ach ``` **Important:** - URL expires after 15 minutes - If expired, generate new download URL - No authentication required (URL contains signature) - Download bandwidth not rate-limited ### Presigned URL Security Model **How It Works:** 1. Twisp generates presigned URL with AWS STS 2. URL contains temporary credentials in query parameters 3. AWS validates signature on access 4. Access granted without exposing permanent credentials **Security Properties:** - Time-limited access (15-minute expiration) - Scoped to specific file key - Cannot be used to access other files - Revoked automatically on expiration - HTTPS only (signatures invalid over HTTP) **Best Practices:** - Generate URLs just before use - Don't store URLs long-term - Don't share URLs externally - Monitor for expired URL errors - Implement retry logic with fresh URLs ### Large File Handling **Upload Optimization:** - Use streaming uploads for large files - Monitor upload progress with Content-Length header - Implement retry logic for network failures - Consider multipart upload for > 50 MB files **Download Optimization:** - Use Range requests for partial downloads - Implement resume capability for interrupted downloads - Stream downloads rather than loading into memory - Consider parallel chunk downloads for very large files ## File History File records maintain complete history of status changes and statistic updates via the `history` connection field queried through [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file). Each version captures: - Processing status at that point in time - Processing detail messages - Statistics snapshot - Modification timestamp - Version number History enables: - Complete audit trail of file processing - Point-in-time analysis of processing state - Debugging processing issues - Compliance and regulatory reporting ## Resolving Workflow Executions for File Records Each parsed record in a file is available through the `records` connection on [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file). When an entry detail record (`ENTRY_DETAIL`, `ADV_ENTRY_DETAIL`, `IAT_ENTRY_DETAIL`) is associated with a workflow trace, its workflow execution can be resolved directly from the record via the `execution` field: ```graphql query FileRecordExecutions { ach { file(fileKey: "incoming-20251114.ach", configId: "config-001") { fileKey fileId records(first: 1000) { nodes { execution { executionId task } record { __typename } } } } } } ``` For a forward entry, `execution` resolves its RDFI workflow. For a matched regular return, it resolves the original ODFI workflow that processed `RETURN`. For a newly processed unmatched regular, dishonored, or contested return, it resolves an `ACH_RDFI_UNMATCHED_RETURN` execution whose ID is the entry record ID. It returns `null` for historical unmatched returns, NOCs, file records, batch records, and control records. From a resolved [WorkflowExecution](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) you can go further — inspect `output`, `error`, and `activities` to trace the transactions an entry's workflow posted. ## File Queries Query files by status using the `PROCESSING_STATUS` index, which requires both `processingStatus` and `configId` filter values. **Supported Filters:** - `configId`: Filter to specific ACH configuration - `processingStatus`: Filter by current processing state - `created`: Filter by file creation timestamp range Results support pagination via standard connection cursors. ## File Operations Use GraphQL for all file operations: **Upload and Processing:** - [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-upload): Create presigned upload URL - [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file): Start file processing - [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file): Get file information by key or ID - [`Query.ach.files()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.files): Query files with status filters **Generation and Download:** - [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file): Generate NACHA file - [`Mutation.files.createDownload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-download): Create presigned download URL - [`Query.files.list()`](https://www.twisp.com/docs/reference/graphql/queries.md#files.list): List files by key prefix ## Further Reading To learn file operations from scratch, see the tutorial on [Setting Up ACH Processing](https://www.twisp.com/docs/tutorials/ach/setting-up-ach.md). For practical file processing workflows, see the how-to guide on [Reconciling ACH Files](https://www.twisp.com/docs/guides/reconciling-ach-files.md). For complete GraphQL type definitions, see: - [AchFileInfo](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info) - [AchProcessingStatistics](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-processing-statistics) - [AchFileType](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-type) - [AchFileProcessingStatus](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-processing-status) - [Upload](https://www.twisp.com/docs/reference/graphql/types/object.md#upload) - [Download](https://www.twisp.com/docs/reference/graphql/types/object.md#download) --- # ACH Reference The Twisp ACH processor handles configuration, file operations, ODFI origination, and RDFI receiving operations. ## ACH Resources See each of the sub-pages in this reference for details about the corresponding ACH resource. Each resource is accessible via the [GraphQL API](https://www.twisp.com/docs/reference/graphql.md). - [Configuration](https://www.twisp.com/docs/reference/ach/configuration.md): ACH configuration defines accounts, webhooks, ODFI headers, and processing parameters. - [File Operations](https://www.twisp.com/docs/reference/ach/file-operations.md): Upload, process, generate, and download NACHA-formatted ACH files. - [ODFI](https://www.twisp.com/docs/reference/ach/odfi.md): Originate ACH transactions via PUSH (credit) and PULL (debit) workflows. - [RDFI](https://www.twisp.com/docs/reference/ach/rdfi.md): Receive and process incoming ACH forward entries, returns, and Notifications of Change. ## Key Concepts of the Twisp ACH Processor _This set of concepts summarizes the key behavior of the Twisp ACH processor._ - **Configuration** defines the operational parameters for ACH processing. - Each configuration connects settlement, suspense, exception, and fee accounts. - Configurations reference webhook endpoints for transaction decisioning. - ODFI header configuration specifies company and bank information for NACHA files. - A direction (`RDFI`, `ODFI`, or `BOTH`) restricts which file types the configuration may process; `BOTH` is the default. - Auto-pending configurations receive RDFI entries into a pending account without webhook decisioning. - Configuration versions are tracked, ensuring file processing references the correct parameters. - **File Operations** manage the complete lifecycle of NACHA-formatted files. - Upload operations create presigned URLs for secure file uploads. - File processing parses NACHA files, validates format, and extracts transactions. - File generation creates NACHA-compliant files from submitted workflow transactions. - Download operations provide presigned URLs for retrieving generated files. - File processing status progresses through states (NEW, VALIDATING, PROCESSING, PENDING, PROCESSED, COMPLETED). - Processing statistics track entry counts and monetary totals in real-time. - **ODFI (Originating Depository Financial Institution)** operations originate ACH transactions. - PUSH workflows send credits (payroll, vendor payments, refunds). - PULL workflows collect debits (bill payments, subscriptions, loan payments). - Workflows manage funds through encumbrance, pending, and settled balance layers. - PUSH workflows settle immediately upon SUBMIT since credits are final. - PULL workflows separate SUBMIT (transmission) from SETTLE (confirmation). - Return processing automatically matches returns to original transactions via trace numbers. - All workflow executions maintain complete audit trails via execution history. - **RDFI (Receiving Depository Financial Institution)** operations receive ACH transactions. - Inbound RDFI files can contain forward entries, returns, and Notifications of Change (NOCs). - Forward entries trigger webhook decisioning for settlement or return instructions. - Auto-pending configurations skip webhooks and post every forward entry to a pending account for manual settlement or return. - Regular returns match originated transactions by their original trace number and execute the `RETURN` task on the original ODFI workflow. - Unmatched regular, dishonored, and contested returns create `ACH_RDFI_UNMATCHED_RETURN` executions, post to the pending account in auto-pending mode or the exception account otherwise, and mark the file as having exceptions. - NOCs and refused NOCs are currently skipped without ledger activity or webhook delivery. - Transactions route to settlement, suspense, or exception accounts based on webhook responses. - RDFI workflows support both CREATE (initial acceptance) and SETTLE (final settlement) states. - Return file generation creates NACHA files for rejected transactions. - **Workflows** execute state transitions for ACH transactions. - Each workflow execution receives a unique execution ID for tracking. - Workflow states (CREATE, SUBMIT, SETTLE, RETURN, CANCEL, REIMBURSE_FEE) define transaction lifecycle. - Ledger transactions are created automatically based on workflow state transitions. - ACH workflow traces link executions to file entries via trace numbers. - Workflow history provides complete audit trail of all state transitions. - **Balance Layers** track transaction lifecycle across multiple states. - Encumbrance layer holds funds during CREATE state before submission. - Pending layer tracks PULL transactions between SUBMIT and SETTLE. - Settled layer contains finalized transactions. - Available balance calculation: Settled - Pending - Encumbrance. - Layer transitions ensure funds are properly accounted at each stage. - **Webhook Decisioning** enables custom business logic for transaction processing. - Webhooks receive POST requests with forward-entry details during RDFI file processing. - Webhook responses specify which account to credit/debit for each transaction. - Transactions can be routed to settlement, suspense, or exception accounts. - Webhook timeouts result in transaction failure requiring manual intervention. - Webhook decisions determine whether transactions settle or return. - **Return Processing** handles rejected transactions from financial institutions. - ODFI returns can be received in an RDFI file alongside forward entries and NOCs, or in an `ODFI_RETURN` file. - RDFI returns are generated for transactions you received and must reject. - Returns automatically match to original transactions via trace numbers. - Return processing executes RETURN workflow state, reversing ledger entries. - Unmatched inbound returns post to the pending account in auto-pending mode or the exception account otherwise for reconciliation. - Return codes (R01-R99) indicate rejection reasons per NACHA standards. - Return files must be transmitted within NACHA-specified timeframes. - **File Types** specify the purpose and direction of ACH files. - RDFI types: RDFI (incoming), RDFI_RETURN (returns to send), RDFI_NOC (notifications). - ODFI types: ODFI (mixed), ODFI_PUSH_ONLY (credits), ODFI_PULL_ONLY (debits), ODFI_RETURN (returns received). - File types control which transactions are included during generation. - Preprocessing file types enable filtering before final file generation. - **Reconciliation** validates file processing and ledger accuracy. - File statistics provide entry counts and monetary totals for validation. - Processing status indicates completion or errors requiring investigation. - The `hasExceptions` field identifies files containing unmatched returns. - Balance reconciliation ensures settlement accounts reflect all ACH activity. - Suspense and exception accounts should be cleared regularly via returns or transfers. - File history enables point-in-time analysis of processing state. ## Further Reading To learn ACH processing from scratch, see: - [Setting Up ACH Processing](https://www.twisp.com/docs/tutorials/ach/setting-up-ach.md) - Complete configuration tutorial - [Your First ACH Payment](https://www.twisp.com/docs/tutorials/ach/first-ach-payment.md) - Send a payment end-to-end For practical production workflows, see: - [Processing ACH Payments](https://www.twisp.com/docs/guides/processing-ach-payments.md) - Daily payment operations - [Handling ACH Returns](https://www.twisp.com/docs/guides/handling-ach-returns.md) - Return management - [Reconciling ACH Files](https://www.twisp.com/docs/guides/reconciling-ach-files.md) - Daily reconciliation For conceptual understanding, see: - [ACH Processor](https://www.twisp.com/docs/processors/ach.md) - How the ACH processor works For complete GraphQL type definitions, see: - [AchConfiguration](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) - [AchFileInfo](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info) - [WorkflowExecution](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) --- # ODFI Reference for ODFI operations within the Twisp ACH Processor ## Overview An ODFI (Originating Depository Financial Institution) originates ACH transactions on behalf of an originator. When operating as an ODFI, the Twisp ACH processor handles transaction lifecycle management, ledger accounting across multiple balance layers, NACHA file generation, and return processing for outgoing ACH payments. The ACH ODFI processor enables you to: - Originate ACH credit (PUSH) and debit (PULL) transactions via workflows - Manage funds through encumbrance, pending, and settled balance layers - Generate NACHA-compliant files for transmission to financial institutions - Track transaction lifecycle from creation through settlement or return - Process returns from RDFIs with automatic ledger reversals - Maintain complete audit trails via workflow execution history ## Getting Started ### Prerequisites Before originating ACH transactions, you need: 1. **ACH Configuration** - Created via [`Mutation.ach.createConfiguration()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.create-configuration) with [direction](https://www.twisp.com/docs/reference/ach/configuration.md#direction) `ODFI` or `BOTH` (an `RDFI`-only configuration cannot process ODFI file types) 2. **Required Accounts** - Settlement, suspense, exception, and fee accounts 3. **Journal** - For posting all ACH transactions 4. **Customer Accounts** - Accounts to debit (PUSH) or credit (PULL) ### Quick Start Example ```graphql # 1. Create required accounts mutation CreateAccounts { # Settlement account - where funds transit during ACH processing settlement: createAccount( input: { accountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" code: "settlement.ach" name: "ACH Settlement" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } # Suspense account - for transactions to unknown accounts suspense: createAccount( input: { accountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" code: "suspense.ach" name: "ACH Suspense" config: { enableConcurrentPosting: true } } ) { accountId } # Exception account - for failed transactions exception: createAccount( input: { accountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" code: "exception.ach" name: "ACH Exception" config: { enableConcurrentPosting: true } } ) { accountId } # Fee account - for ACH processing fees fee: createAccount( input: { accountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" code: "fee.ach" name: "ACH Fee Income" normalBalanceType: CREDIT config: { enableConcurrentPosting: true } } ) { accountId } # Customer account - for testing customer: createAccount( input: { accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" code: "customer.001" name: "Customer Account" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } } # 2. Create a journal for ACH transactions mutation CreateJournal { createJournal( input: { journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" name: "ACH Processing Journal" status: ACTIVE } ) { journalId } } # 3. Create a webhook endpoint (Note: webhook endpoint not used in ODFI-only use cases) mutation CreateACHWebhookProcessor { events { createEndpoint( input: { endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" status: ENABLED endpointType: ACH_PROCESSOR url: "https://webhook.site/ach-testing" subscription: [] description: "ACH webhook processor" } ) { endpointId } } } # 4. Create ACH configuration mutation CreateACHConfig { ach { createConfiguration( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" exceptionAccountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" odfiHeaderConfiguration: { immediateDestination: "021000021" immediateDestinationName: "Federal Reserve Bank" immediateOrigin: "1234567890" immediateOriginName: "Your Company Name" } timeZone: "America/New_York" } ) { configId version } } } ``` ## ODFI Workflows ### Workflow Types There are 2 primary workflow types for originating ACH transactions: 1. **ACH PUSH (Credits)**: Send funds to receivers. Workflow ID `934498b5-b4f1-46c4-ad79-868939dc39e8`. Used for payroll, vendor payments, refunds. 2. **ACH PULL (Debits)**: Collect funds from receivers. Workflow ID `064e3b76-6072-451e-aace-5a7be3704ee2`. Used for bill payments, subscriptions, loan payments. Both workflows accept the same parameters but follow different balance layer progression based on settlement timing requirements. ### PUSH Workflow (ACH Credits) The PUSH workflow originates credit transactions that send funds to receivers. When you execute a PUSH workflow via [`Mutation.workflow.execute()`](https://www.twisp.com/docs/reference/graphql/mutations.md#workflow.execute), funds are immediately encumbered on the customer's account and settled upon submission. #### CREATE State The CREATE state reserves funds and charges processing fees: ```graphql mutation CreatePushTransaction { workflow { execute( input: { executionId:"daf20572-c1b1-11f0-8b14-069b540ea27c" code: "ACH_PUSH" task: "CREATE" params: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" amount: "1500.00" routingNumber: "026009593", accountNumber: "12345678901234567", accountType: "checking", individualName: "Clark Kent", entryDescription: "XFER", effective:"2025-11-14" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" feeAmount: "0.25" correlationId: "payroll-batch-001" metadata: { employeeId: "emp-123" payrollPeriod: "2025-11-01" } entryMetadata: { companyName: "ACME Corp" companyEntryDescription: "PAYROLL" individualName: "John Doe" standardEntryClassCode: "PPD" dfiAccountNumber: "123456789" identificationNumber: "emp-123" rdfiIdentification: "021000021" } } } ) { executionId output { state } } } } ``` **Ledger Entries Created:** Encumbrance layer: ``` DR Customer Account (Encumbrance) $1,500.00 CR Settlement Account (Encumbrance) $1,500.00 ``` Settled layer (fees): ``` DR Customer Account (Settled) $0.25 CR Fee Account (Settled) $0.25 ``` #### SUBMIT State The SUBMIT state finalizes the transaction for file generation: ```graphql mutation SubmitPushTransaction { workflow { execute( input: { executionId:"daf20572-c1b1-11f0-8b14-069b540ea27c" code: "ACH_PUSH" task: "SUBMIT" params: {} } ) { executionId output { state } } } } ``` **Ledger Entries Created:** Reverse encumbrance: ``` DR Customer Account (Encumbrance) -$1,500.00 CR Settlement Account (Encumbrance) -$1,500.00 ``` Post to settled: ``` DR Customer Account (Settled) $1,500.00 CR Settlement Account (Settled) $1,500.00 ``` The transaction is now queued for inclusion in the next file generated via [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file). #### CANCEL State Cancel a transaction before file generation: ```graphql mutation CancelPushTransaction { workflow { execute( input: { executionId:"daf20572-c1b1-11f0-8b14-069b540ea27c" code: "ACH_PUSH" task: "CANCEL" params: {} } ) { executionId output { state } } } } ``` Reverses the CREATE encumbrance. Follow with REIMBURSE_FEE to refund processing fees. ### PULL Workflow (ACH Debits) The PULL workflow originates debit transactions that collect funds from receivers. PULL workflows have an additional SETTLE state between SUBMIT and final settlement. #### CREATE State The CREATE state reserves funds on the settlement account: ```graphql mutation CreatePullTransaction { workflow { execute( input: { executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" code: "ACH_PULL" task: "CREATE" params: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" routingNumber: "026009593", accountNumber: "12345678901234567", accountType: "checking", individualName: "Clark Kent", entryDescription: "XFER", effective:"2025-11-14" amount: "250.00" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" feeAmount: "0.25" correlationId: "billing-batch-001" metadata: { customerId: "cust-456" invoiceNumber: "INV-2025-001" } entryMetadata: { companyName: "ACME Corp" companyEntryDescription: "INVOICE" individualName: "Jane Smith" standardEntryClassCode: "WEB" dfiAccountNumber: "987654321" identificationNumber: "inv-001" rdfiIdentification: "021000021" } } } ) { executionId output { state } } } } ``` **Ledger Entries Created:** Encumbrance layer (inverse of PUSH): ``` DR Settlement Account (Encumbrance) $250.00 CR Customer Account (Encumbrance) $250.00 ``` Settled layer (fees): ``` DR Customer Account (Settled) $0.25 CR Fee Account (Settled) $0.25 ``` #### SUBMIT State The SUBMIT state moves funds to pending layer for file generation: ```graphql mutation SubmitPullTransaction { workflow { execute( input: { executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" code: "ACH_PULL" task: "SUBMIT" params: {} } ) { executionId output { state } } } } ``` **Ledger Entries Created:** Reverse encumbrance: ``` DR Settlement Account (Encumbrance) -$250.00 CR Customer Account (Encumbrance) -$250.00 ``` Post to pending: ``` DR Settlement Account (Pending) $250.00 CR Customer Account (Pending) $250.00 ``` The transaction remains in pending layer until SETTLE execution. #### SETTLE State The SETTLE state finalizes the transaction after collection confirmation: ```graphql mutation SettlePullTransaction { workflow { execute( input: { executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" code: "ACH_PULL" task: "SETTLE" params: {} } ) { executionId output { state } } } } ``` **Ledger Entries Created:** Reverse pending: ``` DR Settlement Account (Pending) -$250.00 CR Customer Account (Pending) -$250.00 ``` Post to settled: ``` DR Settlement Account (Settled) $250.00 CR Customer Account (Settled) $250.00 ``` ### Monitoring Workflow Execution Query workflow execution details using [`Query.workflow.execution()`](https://www.twisp.com/docs/reference/graphql/queries.md#workflow.execution): ```graphql query GetWorkflowExecution { workflow { execution( executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" ) { workflowId executionId task params output { state } activities { action entityType entityId entity { ... on Transaction { transactionId effective description entries(first:4) { nodes { accountId layer amount { units currency } } } } ... on AchWorkflowTrace { traceNumber fileId configId } } } created modified version } } } ``` ## Workflow Parameters All ODFI workflows accept common parameters: - **Account ID**: Customer account to debit (PUSH) or credit (PULL) - **Settlement Account ID**: Central account for fund transit during processing - **Journal ID**: Ledger journal for posting all transactions - **Amount**: Transaction amount in decimal format (e.g., "1500.00") - **Effective Date**: Settlement date in YYYY-MM-DD format - **Fee Account ID** (optional): Account for fee income (default: zero UUID) - **Fee Amount** (optional): Processing fee in decimal format (default: "0") - **Correlation ID**: Unique identifier for grouping related transactions - **Metadata** (optional): Transaction-level JSON metadata - **Entry Metadata** (optional): Entry-level JSON metadata ## PUSH Workflow States PUSH workflows originate credit transactions with immediate settlement upon submission. **Workflow States:** 1. **CREATE**: Initial state creates encumbrance on customer account and charges fees. Funds reserved but not yet transmitted. 2. **CANCEL**: Reverses CREATE encumbrance before file generation. Optionally followed by REIMBURSE_FEE to refund processing fees. 3. **SUBMIT**: Final state settles funds, reversing encumbrance and posting to settled layer. Transaction included in next file generation. 4. **RETURN**: Processes return from RDFI, reversing SUBMIT settlement and returning funds to customer account. 5. **REIMBURSE_FEE**: Refunds processing fee, reversing original fee charge. **Key Characteristic:** PUSH workflows settle immediately on SUBMIT since credit transactions are final upon transmission. ## PULL Workflow States PULL workflows originate debit transactions with delayed settlement pending confirmation. **Workflow States:** 1. **CREATE**: Initial state creates encumbrance on settlement account (inverse of PUSH). Funds reserved awaiting collection. 2. **CANCEL**: Reverses CREATE encumbrance before file generation. 3. **SUBMIT**: Moves funds from encumbrance to pending layer. Transaction included in file but not yet final. 4. **SETTLE**: Final settlement moves funds from pending to settled layer after collection confirmation. 5. **RETURN**: Processes return from RDFI, reversing pending or settled amounts depending on when return received. 6. **REIMBURSE_FEE**: Refunds processing fee on cancellation or return. **Key Characteristic:** PULL workflows separate SUBMIT (transmission) from SETTLE (confirmation) since debit transactions require validation before finalization. ## Transaction Lifecycle and Ledger Accounting The ODFI processor uses multi-stage workflows with double-entry accounting at each stage, tracking funds through multiple balance layers. ### Balance Layers ODFI workflows utilize three balance layers to track transaction lifecycle and fund availability: #### Encumbrance Layer Temporary holds during CREATE state before transmission. Encumbered amounts don't affect available balance calculations but reserve funds for pending transactions. **PUSH (Credits):** ``` DR Customer Account (Encumbrance) CR Settlement Account (Encumbrance) ``` **PULL (Debits):** ``` DR Settlement Account (Encumbrance) CR Customer Account (Encumbrance) ``` The encumbrance layer allows you to: - Reserve funds before file generation - Track expected outflows (PUSH) or inflows (PULL) - Maintain visibility of in-flight transactions - Cancel transactions before file transmission #### Pending Layer PULL workflows only. Tracks transmitted debits awaiting settlement confirmation between SUBMIT and SETTLE states. ``` DR Settlement Account (Pending) CR Customer Account (Pending) ``` The pending layer represents: - Debits transmitted but not yet collected - Funds awaiting final confirmation from RDFI - Transactions that can still be returned #### Settled Layer Final layer for completed transactions. All fees post directly to settled layer. **PUSH SUBMIT:** ``` DR Customer Account (Settled) CR Settlement Account (Settled) ``` **PULL SETTLE:** ``` DR Settlement Account (Settled) CR Customer Account (Settled) ``` **Fees (all workflows):** ``` DR Customer Account (Settled) CR Fee Account (Settled) ``` The settled layer represents final, available balances that affect customer account availability. ### Balance Layer Illustration ``` PUSH (Credit) Flow: ┌─────────────────────────────────────────────────┐ │ CREATE: ENCUMBRANCE Layer │ │ DR Customer Account │ │ CR Settlement Account │ │ • Funds reserved, not yet transmitted │ └─────────────────────────────────────────────────┘ ↓ SUBMIT ┌─────────────────────────────────────────────────┐ │ SUBMIT: SETTLED Layer │ │ DR Customer Account │ │ CR Settlement Account │ │ • Final settlement, funds transmitted │ │ • Included in next file generation │ └─────────────────────────────────────────────────┘ PULL (Debit) Flow: ┌─────────────────────────────────────────────────┐ │ CREATE: ENCUMBRANCE Layer │ │ DR Settlement Account │ │ CR Customer Account │ │ • Collection reserved, not yet transmitted │ └─────────────────────────────────────────────────┘ ↓ SUBMIT ┌─────────────────────────────────────────────────┐ │ SUBMIT: PENDING Layer │ │ DR Settlement Account │ │ CR Customer Account │ │ • Transmitted, awaiting collection │ │ • Included in next file generation │ └─────────────────────────────────────────────────┘ ↓ SETTLE ┌─────────────────────────────────────────────────┐ │ SETTLE: SETTLED Layer │ │ DR Settlement Account │ │ CR Customer Account │ │ • Final settlement, funds collected │ │ • Customer account credited │ └─────────────────────────────────────────────────┘ ``` ### Querying Balances Check account balances across all layers using the standard balance query: ```graphql query GetAccountBalance { balance( accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" currency: "USD" ) { settled { crBalance { units } drBalance { units } } pending { crBalance { units } drBalance { units } } encumbrance { crBalance { units } drBalance { units } } version } } ``` **Available Balance Calculation:** ``` Available = Settled - Pending - Encumbrance (for debits) ``` ### Workflow State Transitions **PUSH Workflow States:** 1. `CREATE` - Reserve funds on customer account (encumbrance) 2. `SUBMIT` - Move to settled, queue for file generation 3. `RETURN` - Reverse settlement if RDFI returns transaction 4. `CANCEL` - Reverse encumbrance before file generation 5. `REIMBURSE_FEE` - Refund processing fee on cancellation/return **PULL Workflow States:** 1. `CREATE` - Reserve collection on settlement account (encumbrance) 2. `SUBMIT` - Move to pending, queue for file generation 3. `SETTLE` - Move to settled after successful collection 4. `RETURN` - Reverse pending/settled if RDFI returns transaction 5. `CANCEL` - Reverse encumbrance before file generation 6. `REIMBURSE_FEE` - Refund processing fee on cancellation/return ## File Generation File generation collects all submitted transactions and creates NACHA-formatted files for transmission to your financial institution or the Federal Reserve. ### Generating Files Use [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file) to create ACH files: ```graphql mutation GenerateODFIFile { ach { generateFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "outgoing-ach-20251114.ach" fileType: ODFI generateEmpty: false } ) { fileKey generated } } } ``` **File Types:** - `ODFI`: Combined file with both PUSH and PULL transactions - `ODFI_PUSH_ONLY`: Credit transactions only - `ODFI_PULL_ONLY`: Debit transactions only **Generation Control:** - `generateEmpty: true`: Always creates file (empty NACHA if no transactions) - `generateEmpty: false`: Only creates file when transactions exist ### File Header Reference Code The file header record reserves positions 87-94 for a Reference Code: eight characters the ACH specification sets aside for information pertinent to the Originator. ACH operators do not act on this field, and it is space-filled by default. Pass `options.fileHeaderReferenceCode` to set it — for example, to match the header layout of files you originate outside Twisp under the same routing number: ```graphql mutation GenerateODFIFile { ach { generateFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "outgoing-ach-20251114.ach" fileType: ODFI generateEmpty: false options: { fileHeaderReferenceCode: "REF00001" } } ) { fileKey generated } } } ``` Accepted values are up to 8 characters of printable ASCII (letters, digits, spaces, and punctuation), with no leading or trailing spaces. Shorter values are right-padded with spaces. Longer values or other characters are rejected with a bad request error. The option applies to every generated file type, including RDFI return and NOC files. ### Supplying the File ID Modifier Twisp assigns the file header's file ID modifier (position 34) from the sequence `A-Z` then `0-9`, or from the range reserved by the configuration. A configuration that sets `userSupplied` on its [File Modifier Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#file-modifier-configuration) hands that choice to you instead, and `options.fileModifier` then becomes required on every generation request: ```graphql mutation GenerateODFIFile { ach { generateFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "outgoing-ach-20251114.ach" fileType: ODFI generateEmpty: false options: { fileModifier: "B" } } ) { fileKey generated } } } ``` Accepted values are a single character from `A-Z` or `0-9`. Twisp writes the character to the file header as given and enforces no sequence of its own: any modifier the day has not used is accepted, in any order. Generation fails with a bad request error when the modifier is missing, when it is not a single character from that sequence, or when it is supplied to a configuration that reserves a range instead. Modifiers stay unique per day whoever chooses them. Twisp records the ones you supply alongside the ones it assigns, so a modifier the day has already written to a file — supplied earlier or assigned from a range the configuration held earlier that day — is refused with an invalid state transition error rather than reissued. Like the reference code, the option applies to every generated file type, including RDFI return and NOC files. ### What Gets Included File generation automatically collects: - All PUSH transactions in SUBMIT state - All PULL transactions in SUBMIT state (pending settlement) - Transactions grouped by effective date and SEC code - Proper batch headers and control totals - File-level hash totals and entry counts ### Balanced Files Generated files are unbalanced by default: batches contain only the forward entries. If your ODFI requires balanced files, set `offsetConfiguration` on the ACH configuration — each batch then ends with an offset entry drawn on the configured account so total credits equal total debits, and batches use service class code 200 (mixed debits and credits). See [Offset Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#offset-configuration-balanced-files) for details. ### NACHA File Structure Generated files contain: 1. **File Header Record** - Configuration from `odfiHeaderConfiguration`: - Immediate destination (your ODFI routing number) - Immediate origin (your company ID) - File creation date/time - File ID modifier, assigned per file in the sequence A-Z then 0-9, or taken from `options.fileModifier` — see [File Modifier Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#file-modifier-configuration) - Reference code (from `options.fileHeaderReferenceCode`, space-filled when omitted) 2. **Batch Header Records** - One per batch: - Service class code (credits, debits, or mixed) - Company name and entry description - Effective entry date - ODFI identification 3. **Entry Detail Records** - One per transaction: - Transaction code (credit/debit, checking/savings) - RDFI routing number - Account number - Amount - Individual name - Trace number 4. **Batch Control Records** - Validates batch totals 5. **File Control Record** - Validates file totals ### Download Generated Files After generation, download files using [`Mutation.files.createDownload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-download): ```graphql mutation DownloadODFIFile { files { createDownload( key: "outgoing-ach-20251114.ach" ) { downloadURL } } } ``` Then download via HTTP GET: ```bash curl '' -o outgoing-ach-20251114.ach ``` Transmit the downloaded file to your ODFI via SFTP, FTPS, or your institution's preferred method. ### File Generation Timing **Best Practices:** - Generate files after your daily processing cutoff - Allow sufficient time for file transmission before ODFI deadlines - Consider timezone settings in your ACH configuration - Generate separate files for different effective dates **Standard ACH Deadlines:** - **Standard ACH**: Submit by 6:00 PM ET for next-day settlement - **Same-Day ACH**: Multiple submission windows (10:30 AM, 2:45 PM ET) - **Weekend Processing**: Transactions submitted Friday settle Monday ## Return Processing Return processing handles transactions rejected by RDFIs. Twisp accepts returns in a mixed inbound `RDFI` file or in a dedicated `ODFI_RETURN` file, matches them to original transactions, and reverses the corresponding ledger entries. ### Return Flow **1. Upload Return File** When you receive an inbound ACH file from your upstream processor, upload it using [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/graphql/mutations.md#files.create-upload): ```graphql mutation CreateReturnUpload { files { createUpload( input: { key: "return-20251114.ach" uploadType: ACH contentType: "text/plain" } ) { uploadURL } } } ``` Upload the file content: ```bash curl -T return-20251114.ach -XPUT '' ``` **2. Process Return File** Choose the processing type based on the contents of the inbound file: - Use `RDFI` when the file can contain forward entries, regular returns, and NOCs. This path routes each entry by its addenda and does not send decisioning webhooks for regular returns or NOCs. - Use `ODFI_RETURN` for a dedicated return-only file. For example, process a dedicated return-only file with [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file): ```graphql mutation ProcessReturnFile { ach { processFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "return-20251114.ach" fileType: ODFI_RETURN } ) { fileId } } } ``` **3. Automatic Return Matching** Twisp automatically: - Extracts trace numbers from return entries - Matches returns to original workflow executions - Executes RETURN workflow state for each transaction - Reverses appropriate balance layer entries - Updates workflow execution history - Creates complete audit trail via `AchWorkflowTrace` For regular returns processed as `RDFI`, Twisp matches the Addenda 99 original trace within the ACH configuration. If no trace matches, or all matching workflows have already returned, Twisp creates an `ACH_RDFI_UNMATCHED_RETURN` execution, posts the return to the pending account in auto-pending mode or the exception account otherwise, and sets `hasExceptions` on the inbound file. NOCs and refused NOCs in the same file are skipped without ledger activity or webhook delivery. **4. Monitor Return Processing** Query file processing status using [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file): ```graphql query GetReturnFileStatus { ach { file( fileKey: "return-20251114.ach" configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" ) { fileId processingStatus processingDetail hasExceptions processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } } } } ``` For files processed as `RDFI`, review unmatched-return postings when `hasExceptions` is `true`. They use the pending account in auto-pending mode and the exception account otherwise. Matched returns and NOCs do not set the field. ### Return Ledger Accounting Returns automatically reverse the appropriate balance layer entries. **PUSH Return (Credit Returned):** If a PUSH transaction in settled layer is returned: ``` Reverse original SUBMIT: DR Settlement Account (Settled) $1,500.00 CR Customer Account (Settled) $1,500.00 ``` Funds are returned to the customer account. **PULL Return (Debit Returned):** If a PULL transaction in pending layer is returned: ``` Reverse original SUBMIT: DR Customer Account (Pending) -$250.00 CR Settlement Account (Pending) -$250.00 ``` If a PULL transaction in settled layer is returned (after SETTLE executed): ``` Reverse original SETTLE: DR Customer Account (Settled) -$250.00 CR Settlement Account (Settled) -$250.00 ``` ### Common Return Codes Returns contain NACHA return codes indicating rejection reason: | Code | Reason | Common Cause | |------|--------|--------------| | `R01` | Insufficient Funds | Receiver account has insufficient balance | | `R02` | Account Closed | Receiver account has been closed | | `R03` | No Account / Unable to Locate | Account number not found at RDFI | | `R04` | Invalid Account Number | Account number fails validation | | `R05` | Unauthorized Debit | Consumer did not authorize debit | | `R07` | Authorization Revoked | Consumer revoked authorization | | `R08` | Payment Stopped | Receiver placed stop payment | | `R10` | Customer Advises Not Authorized | Receiver claims transaction unauthorized | | `R29` | Corporate Customer Not Authorized | Corporate receiver did not authorize | ### Return Timing **Standard Return Windows:** - **Most returns**: Within 2 business days of settlement - **Unauthorized returns** (R05, R07, R10): Up to 60 days after settlement - **Admin returns** (R02, R03, R04): Within 2 business days **Late Returns:** Some returns arrive after the standard 2-day window: - Still processed automatically by Twisp - May require manual reconciliation with your ODFI - Check `processingDetail` for any matching issues ### Handling Return Fees When a transaction is returned, you may want to reimburse processing fees: ```graphql mutation ReimburseFee { workflow { execute( input: { executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" code: "ACH_PUSH" task: "REIMBURSE_FEE" params: {} } ) { executionId output { state } } } } ``` **Ledger Entries:** ``` DR Fee Account (Settled) $0.25 CR Customer Account (Settled) $0.25 ``` ### Return Reconciliation Query workflow execution to see complete return history: ```graphql query GetReturnExecution { workflow { execution( executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" ) { workflowId task params activities { action entity { ... on Transaction { transactionId description entries(first:100) { nodes { accountId layer amount } } } ... on AchWorkflowTrace { traceNumber fileId } } } } } } ``` The `AchWorkflowTrace` entity links the return to the original transaction via trace number, enabling complete auditability. ## Transaction Tracking **Workflow Execution:** Each workflow execution receives unique `executionId` for tracking. Execution record contains: - Workflow and task identifiers - Input parameters - Output state - All created ledger transactions - ACH workflow traces with file and entry details - Complete history of state transitions **ACH Workflow Trace:** Links workflow execution to ACH file entries via: - Trace number (15-digit NACHA identifier) - File ID and record ID - Configuration ID and version - Workflow and execution identifiers Enables return matching, reconciliation, and complete transaction lineage tracking. ## Example : End-to-End ODFI Setup and Payment Complete flow from configuration through file transmission: ```graphql # 1. Create required accounts mutation CreateAccounts { # Settlement account - where funds transit during ACH processing settlement: createAccount( input: { accountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" code: "settlement.ach" name: "ACH Settlement" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } # Suspense account - for transactions to unknown accounts suspense: createAccount( input: { accountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" code: "suspense.ach" name: "ACH Suspense" config: { enableConcurrentPosting: true } } ) { accountId } # Exception account - for failed transactions exception: createAccount( input: { accountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" code: "exception.ach" name: "ACH Exception" config: { enableConcurrentPosting: true } } ) { accountId } # Fee account - for ACH processing fees fee: createAccount( input: { accountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" code: "fee.ach" name: "ACH Fee Income" normalBalanceType: CREDIT config: { enableConcurrentPosting: true } } ) { accountId } # Customer account - for testing customer: createAccount( input: { accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" code: "customer.001" name: "Customer Account" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } } # 2. Create a journal for ACH transactions mutation CreateJournal { createJournal( input: { journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" name: "ACH Processing Journal" status: ACTIVE } ) { journalId } } # 3. Create a webhook endpoint (Note: webhook endpoint not used in ODFI-only use cases) mutation CreateACHWebhookProcessor { events { createEndpoint( input: { endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" status: ENABLED endpointType: ACH_PROCESSOR url: "https://webhook.site/ach-testing" subscription: [] description: "ACH webhook processor" } ) { endpointId } } } # 4. Create ACH configuration mutation CreateACHConfig { ach { createConfiguration( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" exceptionAccountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" odfiHeaderConfiguration: { immediateDestination: "021000021" immediateDestinationName: "Federal Reserve Bank" immediateOrigin: "1234567890" immediateOriginName: "Your Company Name" } timeZone: "America/New_York" } ) { configId version } } } mutation CreatePullTransaction { workflow { execute( input: { executionId: "c97685f6-c1b2-11f0-a959-069b540ea27c" code: "ACH_PULL" task: "CREATE" params: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" routingNumber: "026009593", accountNumber: "12345678901234567", accountType: "checking", individualName: "Clark Kent", entryDescription: "XFER", entryClassCode:"PPD" effective:"2025-11-14" amount: "250.00" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" feeAmount: "0.25" correlationId: "billing-batch-001" metadata: { customerId: "cust-456" invoiceNumber: "INV-2025-001" } entryMetadata: { companyName: "ACME Corp" companyEntryDescription: "INVOICE" individualName: "Jane Smith" standardEntryClassCode: "WEB" dfiAccountNumber: "987654321" identificationNumber: "inv-001" rdfiIdentification: "021000021" } } } ) { executionId output { state } } } } mutation GenerateODFIFile { ach { generateFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "outgoing-ach-20251114.ach" fileType: ODFI generateEmpty: false } ) { fileKey generated } } } mutation DownloadODFIFile { files { createDownload( key: "outgoing-ach-20251114.ach" ) { downloadURL } } } ``` ## Best Practices ### Security **API Key Management:** - Rotate API keys regularly - Use separate keys for production and development - Store keys in secure secret management systems (AWS Secrets Manager, HashiCorp Vault) - Never commit API keys to source control **Account Isolation:** - Use separate ACH configurations for different business units - Implement proper account-level access controls - Audit all ACH operations via workflow execution logs **Webhook Security (if using RDFI):** - Validate webhook signatures to ensure requests are from Twisp - Use HTTPS endpoints for all webhooks - Implement rate limiting and DDoS protection ### Performance **Batch Processing:** - Group transactions by effective date for efficient file generation - Use correlation IDs to track related transactions - Process CREATE and SUBMIT in parallel where possible **Account Configuration:** - Enable `enableConcurrentPosting: true` on all ACH accounts - This supports high-volume parallel transaction posting - Settlement account especially critical for concurrent access **File Generation Timing:** - Generate files during off-peak hours when possible - Separate file generation from transaction creation - Monitor file generation performance via [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file) ### Monitoring **Alert on Key Metrics:** - High return rates (> 2% indicates data quality issues) - Failed workflow executions - File generation failures - Settlement account balance anomalies **Daily Reconciliation:** - Compare file totals with workflow execution totals - Reconcile settlement account with ODFI reports - Track return rates by SEC code and effective date **Execution Tracking:** - Use correlation IDs to group related transactions - Query workflow executions for complete audit trails - Monitor workflow state transitions for stuck transactions ### Compliance **Record Retention:** - Maintain workflow execution history for 7 years minimum - Store generated ACH files and return files - Keep complete audit trail of all balance changes - Archive transaction metadata and authorization records **NACHA Rules:** - Adhere to return timeframes (2 business days for most codes) - Process returns within 24 hours of receipt - Maintain proper SEC codes for transaction types - Follow authorization requirements for debit transactions **Authorization Management:** - Store proof of authorization for debit transactions - Support authorization revocation (R07 returns) - Implement stop payment capabilities (R08 returns) - Handle unauthorized transaction disputes (R10 returns) **Reg E Compliance:** - Honor consumer dispute rights (60-day investigation period) - Provide proper disclosures for recurring debits - Implement error resolution procedures - Maintain consumer authorization records ### Error Handling **Transaction Failures:** - Monitor workflow execution failures - Implement retry logic for transient errors - Use CANCEL state to reverse failed transactions - Alert operations team for manual intervention **Return Handling:** - Process return files within 24 hours of receipt - Automatically reverse transactions via RETURN state - Consider reimbursing fees for returned transactions - Track return rates to identify systemic issues **File Generation Issues:** - Validate all transactions before SUBMIT - Test file generation with `generateEmpty: true` initially - Monitor file processing status via [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file) - Keep backup of generated files before transmission ## ODFI Operations Use GraphQL workflow API for all ODFI operations: - [`Mutation.workflow.execute()`](https://www.twisp.com/docs/reference/graphql/mutations.md#workflow.execute): Execute workflow state transitions - [`Query.workflow.execution()`](https://www.twisp.com/docs/reference/graphql/queries.md#workflow.execution): Get workflow execution details - [`Query.workflow.executions()`](https://www.twisp.com/docs/reference/graphql/queries.md#workflow.executions): Query workflow executions File operations: - [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file): Generate NACHA file - [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file): Process return files - [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file): Query file status ## Further Reading To learn ODFI operations from scratch, see the tutorial on [Your First ACH Payment](https://www.twisp.com/docs/tutorials/ach/first-ach-payment.md). For production payment workflows, see the how-to guide on [Processing ACH Payments](https://www.twisp.com/docs/guides/processing-ach-payments.md). For return management, see the how-to guide on [Handling ACH Returns](https://www.twisp.com/docs/guides/handling-ach-returns.md). For complete GraphQL type definitions, see: - [WorkflowExecution](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) - [AchWorkflowTrace](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-workflow-trace) - [WorkflowExecuteInput](https://www.twisp.com/docs/reference/graphql/types/input.md#workflow-execute-input) --- # RDFI Receive and process incoming ACH transactions as an RDFI ## Overview An RDFI (Receiving Depository Financial Institution) is the financial institution that receives ACH transactions on behalf of a receiver. When operating as an RDFI, the Twisp ACH processor handles incoming ACH files, validates transactions, updates account balances, and generates return files when necessary. The ACH RDFI processor enables you to: - Receive and process ACH credit and debit transactions - Apply transactions to customer accounts with proper ledger accounting - Handle exceptions through suspense and exception accounts - Generate return files for transactions that cannot be processed - Maintain complete audit trails through workflow execution tracking ## Getting Started ### Prerequisites Before processing RDFI files, you need: 1. **ACH Configuration** - Created via `Mutation.ach.createConfiguration()` 2. **Required Accounts** - Settlement, suspense, and exception accounts (a fee account unless the configuration is RDFI-only, and a pending account when using [auto-pending](https://www.twisp.com/docs/reference/ach/rdfi.md#auto-pending-mode)) 3. **Webhook Endpoint** - For receiving transaction decisioning requests (optional in [auto-pending mode](https://www.twisp.com/docs/reference/ach/rdfi.md#auto-pending-mode)) 4. **Journal** - For posting transactions ### Quick Start Example ```graphql # 1. Create webhook endpoint for ACH decisioning mutation CreateEndpoint { events { createEndpoint( input: { endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" status: ENABLED endpointType: ACH_PROCESSOR url: "https://your-domain.com/webhooks/ach" subscription: [] description: "ACH RDFI webhook processor" } ) { endpointId } } } # 2. Create required accounts mutation CreateAccounts { # Settlement account - where funds transit settlement: createAccount( input: { accountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" code: "settlement.ach" name: "ACH Settlement" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } # Suspense account - for transactions to unknown accounts suspense: createAccount( input: { accountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" code: "suspense.ach" name: "ACH Suspense" config: { enableConcurrentPosting: true } } ) { accountId } # Exception account - for failed transactions exception: createAccount( input: { accountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" code: "exception.ach" name: "ACH Exception" config: { enableConcurrentPosting: true } } ) { accountId } # Fee account - for ACH processing fees fee: createAccount( input: { accountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" code: "fee.ach" name: "ACH Fee Income" normalBalanceType: CREDIT config: { enableConcurrentPosting: true } } ) { accountId } } # 3. Create a journal for ACH transactions mutation CreateJournal { createJournal( input: { journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" name: "ACH Processing Journal" status: ACTIVE } ) { journalId } } # 4. Create ACH configuration mutation CreateACHConfig { ach { createConfiguration( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" exceptionAccountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" feeAccountId: "5b9e3c2f-4d0e-5a8f-b6c7-2e9f0a1b3c4d" odfiHeaderConfiguration: { immediateDestination: "021000021" immediateDestinationName: "Your Bank Name" immediateOrigin: "1234567890" immediateOriginName: "Your Company Name" } timeZone: "America/New_York" } ) { configId version } } } ``` ## RDFI Workflow ### 1. Upload ACH File When you receive an ACH file from the Fed or your upstream processor, upload it to Twisp: ```graphql mutation CreateUpload { files { createUpload( input: { key: "incoming-ach-20251114.ach" uploadType: ACH contentType: "text/plain" } ) { uploadURL } } } ``` Upload the file using the returned URL: ```bash curl -T incoming-ach-20251114.ach -XPUT '' ``` ### 2. Process ACH File Start processing the uploaded file: ```graphql mutation ProcessFile { ach { processFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "incoming-ach-20251114.ach" fileType: RDFI } ) { fileId } } } ``` ### 3. Monitor File Processing Check the status of file processing: ```graphql query GetFileStatus { ach { file( fileKey: "incoming-ach-20251114.ach" configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" ) { fileId processingStatus processingDetail hasExceptions processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } } } } ``` **Processing Status Values:** - `NEW` - File created, not yet processing - `UPLOADED` - File uploaded and queued - `VALIDATING` - File format validation in progress - `PARTITIONING` - Preparing for parallel processing - `PROCESSING` - Routing entries and requesting decisions for forward entries (auto-pending: posting entries to the pending account) - `PROCESSED` - All entries processed, awaiting settlements - `PENDING` - Auto-pending entries posted, awaiting manual settle/return - `COMPLETED` - All transactions settled or returned - `ERROR` - Unrecoverable error occurred - `INVALID` - File failed validation For RDFI files, `hasExceptions: true` means that at least one unmatched regular, dishonored, or contested return was processed. Its initial posting uses the pending account when auto-pending is enabled and otherwise uses the exception account. Matched returns and NOCs do not set this field. ### 4. Route Entries and Handle Forward-Entry Webhooks An inbound `RDFI` file can mix forward entries, regular returns, dishonored returns, contested dishonored returns, and NOCs. Twisp routes each record according to its addenda before invoking webhook decisioning: | Record | Processing behavior | Webhook | |--------|---------------------|---------| | Forward credit or debit | Creates an RDFI workflow for settlement or return decisioning | Yes | | Regular return with a matching original trace | Executes `RETURN` on the original ODFI workflow and associates its trace with the inbound return record | No | | Regular return without an eligible original workflow | Creates an `ACH_RDFI_UNMATCHED_RETURN` execution in `CREATE`, posts to the pending account in auto-pending mode or the exception account otherwise, and sets `hasExceptions` on the file. The execution can send `DISHONOR`. | No | | Dishonored return with a matching return trace | Executes `DISHONOR` on the original RDFI workflow. In auto-pending mode, the settled posting goes to the pending account; otherwise it goes to the workflow's current account. | Yes, when the configuration has an endpoint and auto-pending is disabled | | Dishonored return without a matching return trace | Creates an `ACH_RDFI_UNMATCHED_RETURN` execution in `CREATE`, posts to the pending account in auto-pending mode or the exception account otherwise, and sets `hasExceptions` on the file. The execution can send `CONTEST`. | No | | Contested dishonored return with one eligible unmatched-return dishonor trace | Executes `CONTEST` on the `ACH_RDFI_UNMATCHED_RETURN` execution that sent the dishonored return, restoring the funds without sending another response | No | | Contested dishonored return without one eligible unmatched-return dishonor trace | Creates a terminal `ACH_RDFI_UNMATCHED_RETURN` execution in `CREATE`, posts to the pending account in auto-pending mode or the exception account otherwise, and sets `hasExceptions` on the file | No | | NOC or refused NOC | Skips the informational record without ledger activity | No | Regular returns are matched within the ACH configuration by the original trace number in the Addenda 99 record. If multiple workflows share that trace, Twisp selects one that has not already processed `RETURN`. If no trace matches, or all matching workflows have already returned, Twisp treats the entry as unmatched and creates the execution and posting described above. This routing applies to regular Addenda 99 returns. See [Dishonored Returns and Contests](https://www.twisp.com/docs/reference/ach/rdfi.md#dishonored-returns-and-contests) for the dishonor flow. For each forward entry, Twisp sends a webhook to your endpoint. You must respond with instructions on how to handle the transaction. (Configurations with [auto-pending](https://www.twisp.com/docs/reference/ach/rdfi.md#auto-pending-mode) enabled skip this step entirely — every forward entry posts as `PENDING` automatically.) **Webhook Payload Format:** ```json { "workflowName": "ACH.RDFI.CR", "workflowTask": "CREATE", "executionId": "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0", "configurationId": "3a1b9c52-7d44-4f0e-9c1a-2b6e8f4d10aa", "fileId": "8e2c4f17-5b9a-4d3e-8f21-9a7c6b3d5e02", "fileKey": "incoming/ach/20251114/payroll.ach", "fileHeader": { "id": "file-header-id", "immediateDestination": "021000021", "immediateOrigin": "1234567890", "fileCreationDate": "251114", "fileCreationTime": "1030", "fileIDModifier": "A", "immediateDestinationName": "Your Bank Name", "immediateOriginName": "Originating Company", "referenceCode": "" }, "batchHeader": { "id": "batch-id", "serviceClassCode": "220", "companyName": "PAYROLL CO", "companyDiscretionaryData": "", "companyIdentification": "1234567890", "standardEntryClassCode": "PPD", "companyEntryDescription": "PAYROLL", "companyDescriptiveDate": "", "effectiveEntryDate": "251115", "settlementDate": " ", "originatorStatusCode": "1", "odfiIdentification": "12345678", "batchNumber": "0000001" }, "entryDetail": { "id": "entry-id", "transactionCode": "22", "rdfiIdentification": "02100002", "checkDigit": "1", "dfiAccountNumber": "123456789", "amount": "150000", "identificationNumber": "employee-123", "individualName": "John Doe", "discretionaryData": "", "addendaRecordIndicator": "0", "traceNumber": "123456780000001", "category": "Forward" } } ``` The payload identifies the source of the transaction so you can correlate webhooks back to the file and configuration that produced them: - `configurationId` is the ACH configuration that processed the file. - `fileId` is the unique identifier of the file. Use it to look up the file (and group all of its entries) via the [file operations APIs](https://www.twisp.com/docs/reference/ach/file-operations.md). - `fileKey` is the storage key of the file as it was received. - `executionId` uniquely identifies this entry's processing workflow. **Response Format:** You respond with an `action` that tells Twisp how to handle the transaction. The action you return determines which state the entry moves into: ```mermaid graph TD CREATE([CREATE webhook]) -->|your action| D{Decision} D -->|SETTLE| S[SETTLED
auto-settles at when] D -->|PENDING| P[PENDING
held, not auto-settled] D -->|RETURN| R[RETURNED
reversed + added to return file] D -->|RETRY| T[RETRY
webhook redelivered with backoff] P -->|executeTask PENDING
new accountId| P R -->|inbound dishonored return| DH[DISHONOR
settled return] DH[DISHONOR
settled return] -->|executeTask DISHONOR
new accountId| DH P -->|executeTask SETTLE| S P -->|executeTask RETURN| R T -.redelivered.-> CREATE ``` | Action | What it represents | When to use | |--------|--------------------|-------------| | `SETTLE` | Accept the transaction. Twisp encumbers the funds on CREATE and automatically settles them at `when` (or the batch effective date). | The standard path for a transaction you can accept and let Twisp settle on schedule. | | `PENDING` | Accept the transaction but hold it. Twisp posts the encumbrance and then stops — it does **not** auto-settle. You settle or return the entry yourself later, and while it is held you can move the hold to a different account. | You can accept the funds now but need to finish out-of-band review (fraud, compliance, manual approval) before they settle. | | `RETURN` | Reject the transaction. Twisp reverses any encumbrance and records the return so it can be included in a return file. Provide an `addenda99` return code. | The transaction cannot be accepted — insufficient funds, closed or invalid account, unauthorized, etc. | | `RETRY` | Defer the decision. Twisp redelivers the same webhook with exponential backoff. | Your system is temporarily unavailable or you need more time to decide. | #### Option 1: Settle (Accept Transaction) ```json { "action": "SETTLE", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "when": "2025-11-15T00:00:00.000Z", "metadata": { "customerId": "cust-123", "transactionType": "payroll" }, "entryMetadata": { "customerId": "cust-123" } } ``` - `when` is optional. If omitted, uses the effective date from the batch header - If `when` is in the past, the transaction settles immediately - `metadata` is optional and attached to the ledger transaction - `entryMetadata` is optional and attached to the ledger entries #### Option 2: Pending (Accept and Hold) Respond with `PENDING` to accept the transaction into a pending hold layer without settling it. Twisp posts the encumbrance but does **not** schedule automatic settlement — you decide later whether to settle or return the entry. ```json { "action": "PENDING", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "metadata": { "review": "manual_fraud_check", "holdReason": "large_first_time_deposit" }, "entryMetadata": { "customerId": "cust-123" } } ``` - The funds are held on the **encumbrance layer** (`SYS_ACH_ENCUMBRANCE_*` ledger codes), keeping them separate from settled, available balances. - Twisp does not auto-settle a pending entry — it waits until you resolve it. - Resolve the entry by executing a `SETTLE` or `RETURN` task on its workflow execution, using the `executionId` from the webhook payload and the workflow `code` from the webhook's `workflowName` (`ACH.RDFI.CR` → `ACH_RDFI_CR`, `ACH.RDFI.DR` → `ACH_RDFI_DR`): ```graphql mutation ResolvePendingEntry { workflow { executeTask( input: { code: "ACH_RDFI_CR" # or "ACH_RDFI_DR" for debit entries executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" task: "SETTLE" # or "RETURN" } ) { executionId task } } } ``` Use this when you can accept the funds now but need to complete additional review before they become available. ##### Moving a pending hold to a different account While an entry is pending, you can move the held funds to a different account by executing the `PENDING` task again with a new `accountId`. Twisp reverses the encumbrance on the current account and reposts it against the new account — on the same encumbrance layer, atomically: ```graphql mutation MovePendingEntry { workflow { executeTask( input: { code: "ACH_RDFI_CR" # or "ACH_RDFI_DR" for debit entries executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" task: "PENDING" params: { accountId: "1f0e2d3c-4b5a-6978-8695-a4b3c2d1e0f9" } } ) { executionId task } } } ``` - Only entries whose current task is `PENDING` can be moved. Entries that were accepted with `SETTLE`, or that have already settled or returned, reject the move with an invalid state transition error. - A subsequent `SETTLE` or `RETURN` acts on the account currently holding the funds. - Moves can be repeated — each one relocates the hold, including back to a previously used account. - Re-executing `PENDING` with the entry's current `accountId` is a no-op only when the `effective` date is also unchanged. - The reposted hold may take a new `effective` date. The reversal that voids the prior entry always posts at that entry's own effective date; when no `effective` is supplied, the repost keeps the current one. - Allowed `params` are `accountId`, `effective`, `metadata`, and `entryMetadata`; anything else is rejected. - The destination cannot be the ACH configuration's settlement account. #### Option 3: Return (Reject Transaction) ```json { "action": "RETURN", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "addenda99": { "returnCode": "R01", "addendaInformation": "Insufficient Funds" }, "metadata": { "reason": "account_balance_insufficient" } } ``` **Common Return Codes:** - `R01` - Insufficient Funds - `R02` - Account Closed - `R03` - No Account / Unable to Locate Account - `R04` - Invalid Account Number - `R05` - Unauthorized Debit to Consumer Account - `R07` - Authorization Revoked by Customer - `R08` - Payment Stopped - `R10` - Customer Advises Not Authorized [See complete return code reference](https://www.twisp.com/docs/reference/ach/rdfi.md#return-codes) #### Option 4: Retry (Temporary Error) ```json { "action": "RETRY" } ``` Use `RETRY` when: - Your system is temporarily unavailable - You need more time to make a decision - There's a transient error in your processing Twisp will exponentially back off and retry the webhook. ### 5. Generate Return File After processing is complete, generate a return file for any transactions you rejected: ```graphql mutation GenerateReturnFile { ach { generateFile( input: { configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" fileKey: "return-20251114.ach" fileType: RDFI_RETURN generateEmpty: false } ) { fileKey generated } } } ``` `generateEmpty: false` means the file is only created if there are returns to include. Use `options.fileHeaderReferenceCode` to set the file header's Reference Code field (positions 87-94), for example to match the header layout of files you originate outside Twisp. Up to 8 printable ASCII characters, with no leading or trailing spaces; space-filled when omitted. See [File Header Reference Code](https://www.twisp.com/docs/reference/ach/odfi.md#file-header-reference-code) for details. Use `options.fileModifier` to set the file header's file ID modifier (position 34). A single character from `A-Z` or `0-9`, required when the ACH configuration sets `userSupplied` on its [File Modifier Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#file-modifier-configuration) and rejected otherwise. See [Supplying the File ID Modifier](https://www.twisp.com/docs/reference/ach/odfi.md#supplying-the-file-id-modifier) for details. Return files are unbalanced by default. If your financial institution requires balanced files, set `offsetConfiguration` with `enableBalancedReturnNOCs: true` on the ACH configuration — a trailing offset batch then balances the file's totals. See [Offset Configuration](https://www.twisp.com/docs/reference/ach/configuration.md#offset-configuration-balanced-files) for details. ### 6. Download Return File Download the generated return file: ```graphql mutation DownloadReturn { files { createDownload( key: "return-20251114.ach" ) { downloadURL } } } ``` Then download using the URL: ```bash curl '' -o return-20251114.ach ``` Transmit this file to the originating ODFI via your normal file transmission process (SFTP, etc.). ## Auto Pending Mode Auto-pending is a hands-off alternative to webhook decisioning. When an ACH configuration has `autoPending: true`, processing an RDFI file sends **no webhooks**. Every forward entry is automatically posted as `PENDING` to the configuration's pending account, where it waits for you to settle or return it out-of-band. Matched dishonored returns and unmatched returns post to the same account on the settled layer. Use auto-pending when you want to receive files without operating a decisioning endpoint: forward entries, matched dishonored returns, and unmatched returns land in a single pending account, and your reconciliation process resolves them on its own schedule. ### Configuration ```graphql mutation CreateAutoPendingConfig { ach { createConfiguration( input: { configId: "c07e469f-61c9-4bf6-9c18-3f9a44f407d7" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" exceptionAccountId: "4a8f2b1e-3c9d-4f7e-a5b6-1d8e9f0a2b3c" direction: RDFI autoPending: true pendingAccountId: "6c0f4d3e-5e1f-6b9a-c7d8-3f0a1b2c4d5e" odfiHeaderConfiguration: { immediateDestination: "021000021" immediateDestinationName: "Your Bank Name" immediateOrigin: "1234567890" immediateOriginName: "Your Company Name" } timeZone: "America/New_York" } ) { configId version } } } ``` Note what is different from a standard configuration: - `pendingAccountId` is **required** — every forward entry, matched dishonored return, and unmatched return posts here. - `pendingAccountId` must be different from the settlement, suspense, and exception accounts. - `endpointId` is **optional** — auto-pending sends no webhooks, even when an endpoint is configured. - `feeAccountId` is optional because this configuration is `direction: RDFI` (fees only apply to ODFI operations). - `direction` must be `RDFI` or `BOTH`; enabling auto-pending on an `ODFI` configuration is a validation error. ### Processing Behavior Upload and process files exactly as in the [RDFI workflow](https://www.twisp.com/docs/reference/ach/rdfi.md#rdfi-workflow) above. The differences begin after partitioning: 1. Each forward entry posts an encumbrance to the **pending account** — the same posting a webhook `PENDING` response with that account would produce. Matched dishonored returns and unmatched returns post there on the settled layer. 2. Once all entries are posted, the file transitions `PROCESSING → PENDING` (instead of `PROCESSED`). 3. The file holds in `PENDING` while Twisp monitors the entries. When every entry has been settled or returned, the file transitions to `COMPLETED`. ### Resolving Pended Entries Without webhooks, you discover each entry's `executionId` from the file's records via [`Query.ach.file()`](https://www.twisp.com/docs/reference/graphql/queries.md#ach.file): ```graphql query PendedEntries { ach { file(fileKey: "incoming-ach-20251114.ach", configId: "c07e469f-61c9-4bf6-9c18-3f9a44f407d7") { processingStatus records(first: 1000) { nodes { execution { executionId task } } } } } } ``` Entries with `task: "PENDING"` await resolution. Settle or return each one by executing a task on its workflow execution — the same mechanism used to resolve a webhook-pended entry: ```graphql mutation ResolveEntry { workflow { executeTask( input: { executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" task: "SETTLE" # or "RETURN" } ) { executionId task } } } ``` Returned entries are queued for the next [return file generation](https://www.twisp.com/docs/reference/ach/rdfi.md#5-generate-return-file), exactly as in the standard flow. ### Exceptions - If posting to the pending account fails permanently (for example, the account is locked), the entry is posted to the suspense account and queued for return — no webhook is involved. ### Dishonored Returns and Contests When an inbound dishonored return matches a return previously sent by Twisp, Twisp runs the `DISHONOR` task on the original RDFI workflow. Normally, Twisp then sends a dishonor webhook when the ACH configuration has an endpoint. Auto-pending configurations send no webhooks: the dishonor posts on the settled layer of the pending account and remains at `DISHONOR` until you move or contest it through `workflow.executeTask`. The initial `DISHONOR` task accepts an optional `accountId` on any RDFI configuration, posting the dishonored return directly to that account. Auto-pending uses this capability to select the configured pending account. After routing, the dishonor webhook reports the account currently holding the dishonored return, and a later `CONTEST` records that same holding account on the queued contested-return item. It does not preserve the original forward entry's account as a separate field. The dishonor webhook uses the normal ACH webhook endpoint with these contest-specific fields: ```json { "workflowName": "ACH.RDFI.CR", "workflowTask": "DISHONOR", "executionId": "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "addenda99Dishonored": { "dishonoredReturnReasonCode": "R68", "returnTraceNumber": "123456780000002" } } ``` - `workflowTask` is `DISHONOR`. - `executionId` identifies the original RDFI workflow. Use it if you contest the dishonor later through `workflow.executeTask`. - `accountId` is the account currently holding the dishonored return. - `addenda99Dishonored` contains the dishonored-return details received in the file. #### Moving a dishonored return to a different account While a workflow is at `DISHONOR`, you can move its settled posting to a different account by executing `DISHONOR` again with a new `accountId`. You can also annotate the move with `metadata` and `entryMetadata`. Twisp reverses the live dishonor posting on the current account and reposts it against the new account on the same settled layer: In auto-pending mode, the dishonored return initially posts to the configured pending account even though no dishonor webhook is delivered. Name the destination account explicitly when moving it out of that account. ```graphql mutation MoveDishonoredReturn { workflow { executeTask( input: { code: "ACH_RDFI_CR" # or "ACH_RDFI_DR" for debit entries executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" task: "DISHONOR" params: { accountId: "1f0e2d3c-4b5a-6978-8695-a4b3c2d1e0f9" metadata: { operation: "accept_dishonored_return" } entryMetadata: { investigationId: "case-123" } } } ) { executionId task } } } ``` - A subsequent `CONTEST` acts on the account currently holding the funds. - Moves can be repeated, including back to a previously used account. - Re-executing `DISHONOR` is a no-op when the `accountId`, `effective` date, `metadata`, and `entryMetadata` are all unchanged. - The reposted transaction may take a new `effective` date. The reversal always posts at the prior transaction's own effective date; when no `effective` is supplied, the repost keeps the current one. - The allowed `params` are `accountId`, `effective`, `metadata`, and `entryMetadata`. - The destination cannot be the ACH configuration's settlement account. - `metadata` applies to both the void and repost, while `entryMetadata` applies to the repost. These annotations describe this move only; a later transition continues to use the original workflow annotations. - Every move voids the moved-from transaction before reposting, including when the original entry had already settled. On that already-settled path, a later contest is a separate live contra posting and does not void the current dishonor transaction. #### Contest immediately from the webhook Return `CONTEST` to create the contested return immediately: ```json { "action": "CONTEST", "metadata": { "decision": "contest" } } ``` The webhook response cannot set `addenda99Contested`. Twisp chooses the contested return code from the dishonored return code: | Dishonored code | Default contested code | |-----------------|-------------------------| | `R62` | `R77` | | `R67` | `R75` | | `R68` | `R73` | | `R69` | `R74` | | `R70` | `R76` | `R61` has no single default contested code. To contest an `R61`, or to choose a different valid code for any dishonor, use the workflow task path below. #### Contest with a chosen reason code Do not return `action: "CONTEST"` from the dishonor webhook. A response with no action leaves the workflow at `DISHONOR`: ```json {} ``` Then execute the `CONTEST` task with the `executionId` from the webhook. Put the reason code inside `params.addenda99Contested`: ```graphql mutation ContestDishonoredReturn { workflow { executeTask( input: { code: "ACH_RDFI_CR" # or "ACH_RDFI_DR" for debit entries executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" task: "CONTEST" params: { addenda99Contested: { contestedReturnCode: "R71" } metadata: { decision: "misrouted_dishonor" } } } ) { executionId task } } } ``` For `CONTEST`, the caller-settable top-level params are `addenda99Contested`, `effective`, `metadata`, and `entryMetadata`. `effective` is an optional `YYYY-MM-DD` posting date. Twisp reads the account and dishonored-return details from the existing workflow context. Do not put `contestedReturnCode` directly under `params`; it must be nested under `addenda99Contested` as shown above. The `addenda99Contested` object accepts: | Field | Required | Behavior | |-------|----------|----------| | `contestedReturnCode` | No | Must be `R71`, `R72`, `R73`, `R74`, `R75`, `R76`, or `R77`. Twisp keeps the code you provide. When omitted, Twisp uses the default mapping above. It is required for an `R61` dishonor. | | `typeCode` | No | When provided, must be `99`. Twisp sets it to `99` in the generated file. | | `originalSettlementDate` | No | Must be a three-digit ACH Julian day from `001` through `366`. For a matched dishonor, Twisp uses the authoritative settlement date from the original entry. | Twisp derives all trace numbers, return codes, and settlement dates from the matched original entry, return, and dishonored return. Do not send those derived fields. Unknown fields return an error instead of being ignored. If you omit `addenda99Contested`, the workflow uses the same default mapping as an immediate webhook contest: ```graphql params: {} ``` The contest is added to the next generated RDFI return file. IAT contested returns are not supported. ## Transaction Lifecycle and Ledger Accounting The RDFI processor uses a three-stage workflow with double-entry accounting at each stage. ### Stage 1: CREATE (Initial Encumbrance) When a transaction webhook is received, an **encumbrance** is created on the target account: **For Credits (Incoming Deposits):** ``` DR Settlement Account (Encumbrance Layer) CR Customer Account (Encumbrance Layer) ``` **For Debits (Outgoing Withdrawals):** ``` DR Customer Account (Encumbrance Layer) CR Settlement Account (Encumbrance Layer) ``` The encumbrance layer reserves funds but doesn't affect available balance. This allows you to: - Track expected funds before they settle - Maintain visibility of in-flight transactions - Reconcile with external ACH reports ### Stage 2: SETTLE (Final Settlement) When you respond with `"action": "SETTLE"`, two things happen: 1. **Reverse the encumbrance:** ``` Opposite of CREATE entries with negative amounts ``` 2. **Post to settled layer:** ``` DR/CR Customer Account (Settled Layer) DR/CR Settlement Account (Settled Layer) ``` The settled layer represents final, available balances that customers can access. ### Stage 3: RETURN (Rejection) When you respond with `"action": "RETURN"`, the transaction is reversed: 1. **Reverse the encumbrance** (same as SETTLE step 1) 2. **Post return to settled layer** (opposite direction of a normal settlement) 3. **Queue for return file generation** Returns are included in the next return file you generate via `Mutation.ach.generateFile()`. ### Balance Layer Illustration ``` ┌─────────────────────────────────────────────────┐ │ ENCUMBRANCE Layer │ │ • In-flight ACH transactions │ │ • Not available to customer │ │ • Tracks expected debits/credits │ └─────────────────────────────────────────────────┘ ↓ SETTLE ┌─────────────────────────────────────────────────┐ │ SETTLED Layer │ │ • Final, available balance │ │ • Customer can withdraw/spend │ │ • Appears in balance queries │ └─────────────────────────────────────────────────┘ ``` ### Querying Balances Check account balances across all layers: ```graphql query GetAccountBalance { balance( accountId: "d2f7183f-8e9c-45e7-9a98-ef1897ddb930" journalId: "8d7e6f5a-4b3c-2d1e-0f9a-8b7c6d5e4f3a" currency: "USD" ) { settled { crBalance { units currency } drBalance { units currency } } pending { crBalance { units currency } drBalance { units currency } } encumbrance { crBalance { units currency } drBalance { units currency } } version } } ``` **Available Balance Calculation:** ``` Available = Settled - Pending - Encumbrance (for debits) ``` ## Return Generation Create returns for transactions that cannot be processed: ### Return Decision Logic Automatic and manual return triggers: - **Insufficient Funds**: Account balance insufficient for debit - **Account Closed**: Target account no longer active - **Invalid Account**: Account number not found - **Unauthorized**: Transaction not authorized by account holder - **Stop Payment**: Account holder placed stop payment order ### Return Codes Select appropriate return code: - **R01**: Insufficient Funds - **R02**: Account Closed - **R03**: No Account / Unable to Locate Account - **R04**: Invalid Account Number - **R05**: Unauthorized Debit to Consumer Account (improper authorization) - **R07**: Authorization Revoked by Customer - **R08**: Payment Stopped - **R10**: Customer Advises Not Authorized - **R29**: Corporate Customer Advises Not Authorized ### Return Timing Return deadlines by code: - **2 Business Days**: Most return codes (R01-R04, R07-R08, etc.) - **60 Calendar Days**: Unauthorized returns (R05, R07, R10, R29) - **Next Business Day**: Same-day ACH returns ### Return File Generation Create NACHA return files: - **Return Entry**: Create return detail record in Twisp - **Return Batch**: Group returns in batches - **Return File Generation**: Generate complete NACHA return file via Files API - **File Download**: Retrieve generated return file from Twisp - **File Transmission**: You transmit return file to originating ODFI via SFTP/FTPS ## Monitoring and Observability ### Query Files by Status Find all files in a specific processing state: ```graphql query GetProcessingFiles { ach { files( first: 100 index: { name: PROCESSING_STATUS } where: { configId: { eq: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" } processingStatus: { eq: "PROCESSING" } created: { gte: "2025-11-01T00:00:00Z" } } ) { nodes { fileId fileKey processingStatus processingDetail hasExceptions processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } created modified } pageInfo { hasNextPage endCursor } } } } ``` After processing, review files where `hasExceptions` is `true` and reconcile their unmatched-return transactions. The initial posting is in the pending account for auto-pending configurations and the exception account otherwise. Those transactions use the inbound file ID as their correlation ID and retain the complete parsed RDFI workflow entry in their transaction and entry metadata. ### Track Workflow Execution Forward entries create RDFI workflow executions that you can query. A matched regular return resolves the original ODFI workflow execution that processed `RETURN`. Newly processed unmatched regular, dishonored, and contested returns resolve an `ACH_RDFI_UNMATCHED_RETURN` execution whose execution ID is the entry record ID. Historical unmatched returns, NOCs, file records, batch records, and control records resolve `null`. ```graphql query GetWorkflowExecution { workflow { execution( executionId: "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0" ) { workflowId executionId task params output { state } activities { action entityType entityId entity { ... on Transaction { transactionId effective description } ... on AchWorkflowTrace { traceNumber fileId configId } } } created modified version } } } ``` The `activities` field shows all transactions and ACH traces created by this workflow, giving you complete auditability. ## Exception Handling ### Suspense Account When a transaction targets an account that doesn't exist, it's automatically posted to your configured `suspenseAccountId`. This allows you to: 1. Accept the transaction (avoiding a return) 2. Research the correct account 3. Create a manual journal entry to move funds to the correct account **Example scenario:** - ACH credit arrives for account number "123456789" - Account doesn't exist in your system - Transaction is posted: ``` DR Settlement Account CR Suspense Account ``` - You investigate and find the correct account is "123456790" - You create a journal entry to move the funds: ``` DR Suspense Account CR Correct Customer Account ``` ### Exception Account When a transaction fails due to velocity controls, account state issues, or other processing errors, it's posted to your `exceptionAccountId`. An unmatched inbound return is also posted there unless auto-pending is enabled, in which case its initial posting uses the pending account. Common scenarios: - **Velocity Control Violation**: Transaction exceeds configured velocity limits - **Account Locked**: Target account is frozen or locked - **Processing Error**: Temporary system issue - **Unmatched Return**: No ODFI workflow matches the return's original trace number, or all matching workflows have already returned Unmatched regular, dishonored, and contested returns use transaction code `SYS_ACH_UNKNOWN_RETURN_CR` or `SYS_ACH_UNKNOWN_RETURN_DR`, post against the settlement account at the `SETTLED` layer, and set `hasExceptions` on the file. New records also create an `ACH_RDFI_UNMATCHED_RETURN` execution using the entry record ID as both the execution ID and CREATE transaction ID. The inbound file ID is the correlation ID, and the complete parsed RDFI workflow entry is available in transaction and entry metadata for reconciliation. Historical unmatched postings are not backfilled and have no execution. With auto-pending and a configured pending account, CREATE uses that pending account; otherwise it uses the exception account. CREATE, DISHONOR, and CONTEST override velocity enforcement to `WARN` because they represent network obligations. For an unmatched regular return, execute `DISHONOR` to reverse CREATE and queue a dishonored return. For an unmatched dishonored return, execute `CONTEST` to reverse CREATE and queue a contested return. Both tasks accept an optional `accountId`; when omitted, Twisp uses the account selected by the current state. An inbound contest received after DISHONOR restores CREATE against the account selected by DISHONOR and queues no further response. The current task may also be executed again to correct its live posting. A self-transition accepts optional `accountId`, `effective`, `metadata`, and `entryMetadata`; omitted fields keep their current values. Twisp voids the current posting and reposts it with the new account, date, or annotations. It does not queue or retransmit an ACH reply. An unchanged request succeeds without posting. A later lifecycle task defaults to the account selected by the latest correction. An unmatched contested return remains in `CREATE`, because NACHA defines no further reply. Its `CREATE` task can repeat for account, effective-date, or metadata corrections, while `DISHONOR` and `CONTEST` are invalid. `DISHONOR` accepts an optional complete `addenda99Dishonored` JSON object. When absent, Twisp builds an R61 addenda from the inbound return. `CONTEST` on an unmatched dishonored return accepts an optional complete `addenda99Contested` object. When absent, Twisp builds R71 and leaves `originalSettlementDate` and `dateOriginalEntryReturned` blank. A supplied valid NACHA reason code and its business fields are preserved; Twisp assigns the outbound trace number and physical line number. Malformed JSON, unknown fields, invalid widths or characters, invalid reason codes, and missing reason-dependent fields fail before posting money or queuing a response. Dishonored and contested replies for IAT and ADV entries are not supported. The initial trace lookup is final for a processing attempt, so a redrive does not reclassify an unknown record using a trace that appeared later. Direct callers of `SYS_ACH_UNKNOWN_RETURN_CR` or `SYS_ACH_UNKNOWN_RETURN_DR` must pass the holding-side account as `accountId`; the former `exceptionAccountId` parameter is no longer accepted. Funds from rejected forward entries should typically be returned to the originator via a return file. Unmatched inbound returns require manual investigation and reconciliation against their current holding account. ### Velocity Control Integration The RDFI processor enforces any [velocity controls](https://www.twisp.com/docs/reference/ledger/velocity-controls.md) attached to the target account. Enforcement happens when the entry is posted — at the `ENCUMBRANCE` layer during **CREATE** and at the `SETTLED` layer during **SETTLE**. **If a velocity control is tripped, Twisp automatically executes a return** rather than posting the transaction. This applies at both states: - At **CREATE**, if encumbering the funds would exceed a limit, the entry is returned instead of being accepted (regardless of the `SETTLE`/`PENDING` action you responded with). - At **SETTLE**, if final settlement would exceed a limit, the entry is returned at settlement time. This provides built-in protection against overdrafts and unauthorized transactions without requiring you to track balances yourself. **Overriding enforcement for a specific entry:** the `metadata` and `entryMetadata` you return on the webhook response are attached to the transaction and its entries, and are visible to a velocity control's [`condition`](https://www.twisp.com/docs/reference/ledger/velocity-controls.md); a CEL expression that decides whether an entry is eligible to apply to the limit. By writing a `condition` that reads these values, you can exempt specific entries from a control (for example, tagging `entryMetadata.override: "approved"` and excluding those entries in the limit's condition). ## Practical Examples ### Example 1: Basic RDFI Setup and Processing Complete flow from setup to settlement: ```graphql # Step 1: Setup (run once) mutation Setup { # Create webhook endpoint endpoint: events { createEndpoint( input: { endpointId: "webhook-001" status: ENABLED endpointType: ACH_PROCESSOR url: "https://api.yourcompany.com/ach/webhook" subscription: [] } ) { endpointId } } # Create journal journal: createJournal( input: { journalId: "journal-001" name: "ACH Journal" status: ACTIVE } ) { journalId } # Create accounts (abbreviated) settlement: createAccount( input: { accountId: "acct-settlement" code: "settlement" name: "ACH Settlement" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } # Create ACH config config: ach { createConfiguration( input: { configId: "config-001" endpointId: "webhook-001" journalId: "journal-001" settlementAccountId: "acct-settlement" suspenseAccountId: "acct-suspense" exceptionAccountId: "acct-exception" feeAccountId: "acct-fee" odfiHeaderConfiguration: { immediateDestination: "021000021" immediateDestinationName: "Federal Reserve Bank" immediateOrigin: "1234567890" immediateOriginName: "Your Company" } timeZone: "America/New_York" } ) { configId } } } # Step 2: Upload file (when received from Fed) mutation UploadFile { files { createUpload( input: { key: "incoming-20251114-001.ach" uploadType: ACH contentType: "text/plain" } ) { uploadURL } } } # Use uploadURL to PUT file content # Step 3: Process file mutation ProcessFile { ach { processFile( input: { configId: "config-001" fileKey: "incoming-20251114-001.ach" fileType: RDFI } ) { fileId } } } # Step 4: Monitor processing query MonitorFile { ach { file( fileKey: "incoming-20251114-001.ach" configId: "config-001" ) { processingStatus processingStatistics { numEntriesUnprocessed totalCreditAmount totalDebitAmount } } } } # Step 5: Generate returns (after webhooks complete) mutation GenerateReturns { ach { generateFile( input: { configId: "config-001" fileKey: "return-20251114-001.ach" fileType: RDFI_RETURN generateEmpty: false } ) { fileKey generated } } } # Step 6: Download returns mutation DownloadReturns { files { createDownload( key: "return-20251114-001.ach" ) { downloadURL } } } ``` ### Example 2: Webhook Handler Implementation Sample webhook handler in Node.js: ```javascript app.post('/ach/webhook', async (req, res) => { const { workflowName, workflowTask, executionId, entryDetail } = req.body; try { // Extract transaction details const accountNumber = entryDetail.dfiAccountNumber; const amount = parseFloat(entryDetail.amount) / 100; // Amount is in cents const isDebit = entryDetail.transactionCode.startsWith('2'); // 22, 23, 24 const isCredit = entryDetail.transactionCode.startsWith('3'); // 32, 33, 34 // Look up customer account const account = await findAccountByNumber(accountNumber); if (!account) { // Account not found - will go to suspense return res.json({ action: 'SETTLE', accountId: SUSPENSE_ACCOUNT_ID, metadata: { reason: 'account_not_found', originalAccountNumber: accountNumber } }); } if (account.status === 'CLOSED') { // Account closed - return with R02 return res.json({ action: 'RETURN', accountId: account.id, addenda99: { returnCode: 'R02', addendaInformation: 'Account Closed' } }); } if (isDebit) { // Check balance for debits const balance = await getAccountBalance(account.id); if (balance < amount) { return res.json({ action: 'RETURN', accountId: account.id, addenda99: { returnCode: 'R01', addendaInformation: 'Insufficient Funds' } }); } } // All checks passed - settle the transaction return res.json({ action: 'SETTLE', accountId: account.id, when: new Date().toISOString(), // Settle immediately metadata: { customerId: account.customerId, originalTraceNumber: entryDetail.traceNumber } }); } catch (error) { console.error('Webhook processing error:', error); // Retry on errors return res.json({ action: 'RETRY' }); } }); ``` ## API Reference ### GraphQL Operations **Configuration:** - `Query.ach.configuration(id: UUID!)` - Get ACH configuration - `Query.ach.configurations(first: Int!)` - List all configurations - `Mutation.ach.createConfiguration(input: AchCreateConfigurationInput!)` - Create configuration - `Mutation.ach.updateConfiguration(configId: UUID!, input: AchUpdateConfigurationInput!)` - Update configuration **File Operations:** - `Query.ach.file(id: UUID, fileKey: String, configId: UUID)` - Get file status - `Query.ach.files(index: AchFileInfoIndexInput!, where: AchFileInfoFilterInput!, first: Int!)` - Query files - `Mutation.ach.processFile(input: AchProcessFileInput!)` - Process uploaded file - `Mutation.ach.generateFile(input: AchGenerateFileInput!)` - Generate return/NOC file - `Mutation.files.createUpload(input: CreateUploadInput!)` - Get upload URL - `Mutation.files.createDownload(key: String!)` - Get download URL **Workflow Operations:** - `Query.workflow.execution(executionId: UUID!)` - Get workflow execution details - `Mutation.workflow.executeTask(input: WorkflowInput!)` - Settle or return a pending entry, move a live posting, or send a dishonored or contested return ## Return Codes Reference When returning a transaction, use the appropriate return code in the `addenda99.returnCode` field. ### Standard Return Codes | Code | Reason | Description | Timing | |------|--------|-------------|--------| | `R01` | Insufficient Funds | Available balance is not sufficient to cover the dollar value of the debit entry | 2 business days | | `R02` | Account Closed | Previously active account has been closed by customer or RDFI | 2 business days | | `R03` | No Account/Unable to Locate Account | Account number structure is valid and passes editing process, but does not correspond to individual or is not an open account | 2 business days | | `R04` | Invalid Account Number | Account number structure not valid; entry may fail check digit validation or may contain an incorrect number of digits | 2 business days | | `R05` | Improper Debit to Consumer Account | A CCD, CTX, or CBR debit entry was transmitted to a Consumer Account of the Receiver and was not authorized by the Receiver | 60 days | | `R06` | Returned per ODFI's Request | ODFI has requested RDFI to return the ACH entry (optional to RDFI - ODFI indemnifies RDFI) | 2 business days | | `R07` | Authorization Revoked by Customer | Consumer, who previously authorized ACH payment, has revoked authorization from Originator | 60 days | | `R08` | Payment Stopped | Receiver of a recurring debit transaction has stopped payment to a specific ACH debit | 2 business days | | `R09` | Uncollected Funds | Sufficient book or ledger balance exists to satisfy dollar value of the transaction, but the dollar value of transaction is in process of collection | 2 business days | | `R10` | Customer Advises Originator is Not Known to Receiver and/or Originator is Not Authorized | The receiver does not know the Originator's identity and/or has not authorized the Originator to debit | 60 days | | `R11` | Customer Advises Entry Not in Accordance with the Terms of the Authorization | The Originator and Receiver have a relationship, and an authorization to debit exists, but there is an error or defect in the payment | 60 days | | `R12` | Branch Sold to Another DFI | Financial institution receives entry destined for an account at a branch that has been sold to another financial institution | 2 business days | | `R13` | RDFI not qualified to participate | Financial institution does not receive commercial ACH entries | 2 business days | | `R14` | Representative payee deceased or unable to continue in that capacity | The representative payee authorized to accept entries on behalf of a beneficiary is either deceased or unable to continue in that capacity | 2 business days | | `R15` | Beneficiary or bank account holder deceased | (1) the beneficiary entitled to payments is deceased or (2) the bank account holder other than a representative payee is deceased | 2 business days | | `R16` | Bank account frozen | Funds in bank account are unavailable due to action by RDFI or legal order | 2 business days | | `R17` | File record edit criteria | Fields rejected by RDFI processing (identified in return addenda) | 2 business days | | `R20` | Non-payment bank account | Entry destined for non-payment bank account defined by regulation | 2 business days | | `R23` | Credit entry refused by receiver | Receiver returned entry because minimum or exact amount not remitted, bank account is subject to litigation, or payment represents an overpayment | 2 business days | | `R29` | Corporate customer advises not authorized | RDFI has been notified by corporate receiver that debit entry of originator is not authorized | 2 business days | ### Best Practices **Return Timing:** - Most returns must be sent within **2 business days** of settlement date - Unauthorized returns (R05, R07, R10, R11) can be returned up to **60 days** after settlement - Same-day ACH returns must be sent by the same business day **Common Scenarios:** ```javascript // Insufficient funds { "action": "RETURN", "accountId": "account-id", "addenda99": { "returnCode": "R01", "addendaInformation": "Insufficient Funds" } } // Account closed { "action": "RETURN", "accountId": "account-id", "addenda99": { "returnCode": "R02", "addendaInformation": "Account Closed" } } // Account not found { "action": "RETURN", "accountId": "account-id", "addenda99": { "returnCode": "R03", "addendaInformation": "No Account" } } // Unauthorized transaction { "action": "RETURN", "accountId": "account-id", "addenda99": { "returnCode": "R10", "addendaInformation": "Not Authorized" } } ``` ## Best Practices ### Security - **Webhook Authentication**: Validate webhook signatures to ensure requests are from Twisp - **HTTPS Only**: Always use HTTPS endpoints for webhooks - **Idempotency**: Handle duplicate webhooks gracefully using `executionId` ### Performance - **Fast Webhook Response**: Respond to webhooks within 30 seconds - **Async Processing**: Queue webhook processing if complex logic is needed - **Retry Logic**: Implement exponential backoff for webhook retries ### Monitoring - **Alert on Status Changes**: Monitor file processing status for errors - **Track Return Rates**: High return rates may indicate data quality issues - **Balance Reconciliation**: Daily reconciliation of settlement account ### Compliance - **Return Timeframes**: Adhere to NACHA return deadlines (2 days for most codes) - **Authorization Records**: Maintain proof of authorization for debits - **Transaction History**: Keep complete audit trail for 7 years - **Reg E Compliance**: Honor consumer dispute rights (60-day investigation period) ## Further Reading For practical guidance on receiving ACH transactions: - [Handling ACH Returns and NOCs](https://www.twisp.com/docs/guides/handling-ach-returns.md) - Return processing and NOC management - [Reconciling ACH Files](https://www.twisp.com/docs/guides/reconciling-ach-files.md) - File validation and reconciliation procedures - [Processing ACH Payments](https://www.twisp.com/docs/guides/processing-ach-payments.md) - Risk management and best practices For additional technical details: - [Configuration](https://www.twisp.com/docs/reference/ach/configuration.md) - RDFI configuration parameters - [File Operations](https://www.twisp.com/docs/reference/ach/file-operations.md) - File upload and parsing API specifications - [ODFI Reference](https://www.twisp.com/docs/reference/ach/odfi.md) - Origination perspective - [ACH Processor](https://www.twisp.com/docs/processors/ach.md) - Conceptual overview --- # Authentication Authenticating requests against the Twisp API. Twisp authenticates GraphQL API requests with a JSON Web Token (JWT). The token must identify a principal that has a corresponding Twisp client configuration; Twisp then evaluates that client's policies to authorize the requested operation. ## Request headers Send the JWT and the Twisp account ID with every GraphQL API request: ```http Authorization: Bearer x-twisp-account-id: ``` Twisp accepts tokens issued by an OpenID Connect (OIDC) provider. For OIDC tokens, the issuer in the `iss` claim is typically used as the principal name. Twisp can also exchange a presigned AWS STS `GetCallerIdentity` request for a token whose principal represents the AWS identity. ## Authorization Authentication establishes the caller's identity; client policies determine what that identity may do. A client must exist for the token's principal and have policies that allow the requested action on the requested resource. A matching `DENY` policy takes precedence over an `ALLOW` policy. See [Security and Auth](https://www.twisp.com/docs/infrastructure/security-and-auth.md) for instructions on creating clients, configuring OIDC or AWS IAM principals, and defining authorization policies. --- # Errors Error codes returned by the Twisp API when things don't go right. This reference lists the types of errors that may be encountered. ## Error Responses The API uses a response format conforming to the [GraphQL spec](https://spec.graphql.org/October2021/#sec-Response-Format). For more information, see the docs on [Response Format](https://www.twisp.com/docs/reference/api/response-format.md). > If the request raised any errors, the response map must contain an entry with key `errors`. The value of this entry is described in the “Errors” section. If the request completed without raising any errors, this entry must not be present. Because the Twisp API supports [Transactional Operations](https://www.twisp.com/docs/reference/api/transactional-operations.md), if there are _any_ errors, then the entire operation is aborted and the `"data"` field will be `null`. ## Example Response This example shows the response of an `createAccount` operation with a malformed `accountId`. **Request** ```graphql mutation INVALID_UUID_LENGTH { createAccount( input: { accountId: "" code: "TEST" name: "TEST" normalBalanceType: DEBIT status: ACTIVE } ) { accountId } } ``` **Response** ```json { "errors": [ { "message": "input: createAccount.input.accountId invalid UUID length: 0", "path": ["createAccount", "input", "accountId"], "extensions": { "code": "UUID_PARSE_ERROR", "retriableError": false } } ], "data": null } ``` The response indicates that there was an error with the `createAccount` mutation request. The error is a `UUID_PARSE_ERROR`, which means that the `accountId` field in the request has an invalid UUID value. Within the `errors` array, each error object contains fields specifying more information about the error: - `message` summarizes the error, and may give a clue to its cause. In this example, it indicates that the `accountId` field has an invalid length, which is 0. - `path` specifies the location within the GraphQL operation that the error occurred. In this example, it indicates that the error occurred in the `accountId` field of the `input` argument provided to the `createAccount` mutation. - `extensions` provides additional information about the error. - `extensions.code` specifies the **error code** used to represent the error. In this example, the code is `UUID_PARSE_ERROR`. The `data` field in the response is `null` since the request was not successful due to the error. To resolve this particular error, a valid UUID value should be provided for the `accountId` field. An empty string is not a valid UUID value. ## Error Codes ### ACCESS_DENIED Indicates that the request was denied due to a lack of proper authentication or authorization. ### ALREADY_EXISTS Indicates that the requested resource already exists and cannot be created again. ### BAD_REQUEST Indicates that the request was malformed or invalid. For example, a missing `eq` in the partition key: **Request** ```graphql query EqRequiredForPartitionKey { accounts( index: { name: ACCOUNT_ID } where: { accountId: { like: "foo" } } first: 10 ) { nodes { accountId name } } } ``` **Response** ```json { "errors": [ { "message": "input: accounts eq required for account_id partition key", "path": ["accounts"], "extensions": { "code": "BAD_REQUEST", "retriableError": false } } ], "data": null } ``` Or a missing partition key: **Request** ```graphql query PartitionKeyRequired { accounts( index: { name: ACCOUNT_ID } where: { name: { eq: "TESTACCT" } } first: 10 ) { nodes { accountId name } } } ``` **Response** ```json { "errors": [ { "message": "input: accounts account_id partition key required", "path": ["accounts"], "extensions": { "code": "BAD_REQUEST", "retriableError": false } } ], "data": null } ``` ### CEL_EVALUATION_ERROR Indicates that there was an error evaluating a CEL expression. ### DATE_PARSE_ERROR Indicates that there was an error parsing a date string. **Request** ```graphql mutation DATE_PARSE_ERROR { postTransaction( input: { transactionId: "981b7bbd-2d70-4975-90d3-027ee9d8be77" tranCode: "TESTTC" params: { accountId: "7052f9fd-dd15-40d0-b0b6-df8c4c372e41" effectiveDate: "{2022-12-21}" } } ) { transactionId } } ``` **Response** ```json { "errors": [ { "message": "input: postTransaction parsing time \"{2022-12-21}\" as \"2006-01-02\": cannot parse \"{2022-12-21}\" as \"2006\"", "path": ["postTransaction"], "extensions": { "code": "DATE_PARSE_ERROR", "retriableError": false } } ], "data": null } ``` ### DEPENDENCY_ERROR Indicates that there was an error with a dependent resource. **Request** ```graphql mutation DEPENDENCY_ERRORS { missingRequiredParam: postTransaction( input: { transactionId: "f82391bb-90a7-4328-b5ad-8629a7602de8" tranCode: "TESTTC" params: { accountId: "7052f9fd-dd15-40d0-b0b6-df8c4c372e41" } } ) { transactionId } } ``` **Response** ```json { "errors": [ { "message": "input: missingRequiredParam param 'effectiveDate' not defined", "path": ["missingRequiredParam"], "extensions": { "code": "DEPENDENCY_ERROR", "retriableError": false } } ], "data": null } ``` ### ENUM_PARSE_ERROR Indicates that there was an error parsing an enumeration value. **Request** ```graphql query GetJournalsInvalidStatus { journals( index: { name: STATUS } where: { status: { eq: "FOO" } } first: 100 ) { nodes { name status created } } } ``` **Response** ```json { "errors": [ { "message": "input: journals journal status enum 'FOO' not found", "path": ["journals"], "extensions": { "code": "ENUM_PARSE_ERROR", "retriableError": false } } ], "data": null } ``` ### FOREIGN_KEY_VIOLATION Indicates that there was an error with a foreign key constraint. ### GRAPHQL_PARSE_FAILED Indicates that there was an error parsing the GraphQL query. **Request** ```graphql mutation 82* ``` **Response** ```json { "errors": [ { "message": "Expected {, found Int", "locations": [{ "line": 1, "column": 10 }], "extensions": { "code": "GRAPHQL_PARSE_FAILED", "retriableError": false } } ], "data": null } ``` ### GRAPHQL_VALIDATION_FAILED Indicates that there was an error validating the GraphQL query. **Request** ```graphql query first_should_be_int { accounts(first: "10") { nodes { accountId } } } ``` **Response** ```json { "errors": [ { "message": "Int cannot represent non-integer value: \"10\"", "locations": [{ "line": 2, "column": 20 }], "extensions": { "code": "GRAPHQL_VALIDATION_FAILED", "retriableError": false } }, { "message": "Field \"accounts\" argument \"index\" of type \"AccountIndexInput!\" is required, but it was not provided.", "locations": [{ "line": 2, "column": 3 }], "extensions": { "code": "GRAPHQL_VALIDATION_FAILED", "retriableError": false } } ], "data": null } ``` ### INTERNAL_SERVER_ERROR Indicates that there was an error on the server that prevented it from fulfilling the request. ### INTERRUPTED Indicates that the request was interrupted. ### JSON_PARSE_ERROR Indicates that there was an error parsing a JSON string. **Request** ```graphql mutation JSON_PARSE_ERROR { invalidParams: postTransaction( input: { transactionId: "e0995c6f-1a25-42f2-b2f2-568cf91f0487" tranCode: "TESTTC" params: "" } ) { transactionId } } ``` **Response** ```json { "errors": [ { "message": "input: invalidParams.input.params invalid JSON format", "path": ["invalidParams", "input", "params"], "extensions": { "code": "JSON_PARSE_ERROR", "retriableError": false } } ], "data": null } ``` ### NOT_FOUND Indicates that the requested resource was not found. ### NOT_SUPPORTED Indicates that the requested operation is not supported. ### TIMESTAMP_PARSE_ERROR Indicates that there was an error parsing a timestamp. ### TRAN_CODE_ERROR Indicates that there was an error with a transaction code. For example, with unbalanced entries: **Request** ```graphql mutation CreateTranCode { createTranCode( input: { tranCodeId: "74e90f0a-5ffa-4fce-9880-1bc976b59937" code: "TFR_TEST" description: "Transfer $1 from one account to another" params: [ { name: "effectiveDate", type: DATE } { name: "fromAccount" type: UUID description: "Account to send funds from." } { name: "toAccount" type: UUID description: "Recipient account. Required." } { name: "amount", type: DECIMAL, default: "1.00" } ] transaction: { journalId: "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')" effective: "params.effectiveDate" } entries: [ { accountId: "params.fromAccount" units: "params.amount" currency: "'USD'" description: "metadata.tags + ' from'" entryType: "'TRANSFER_DR'" direction: "DEBIT" layer: "SETTLED" } ] metadata: { tags: "xfer" } } ) { tranCodeId code transaction { effective } entries { accountId units entryType direction layer } metadata } } ``` **Response** ```json { "errors": [ { "message": "input: createTranCode 'TFR_TEST' tran code entries unbalanced: 'DR 1.00 USD != 'CR 0 USD'", "path": ["createTranCode"], "extensions": { "code": "TRAN_CODE_ERROR", "retriableError": false } } ], "data": null } ``` Another example, with a syntax error: **Request** ```graphql mutation TRAN_CODE_ERROR { # Invalid CEL syntax in transaction.effective tc1: createTranCode( input: { tranCodeId: "B852FEA6-3445-49E7-BFD4-A162EEC08017" code: "ABC123" description: "an example tran code" params: [{ name: "amount", type: DECIMAL }] transaction: { effective: "{time.Now()}" journalId: "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')" } entries: [ { entryType: "EXAMPLE" accountId: "uuid('7052f9fd-dd15-40d0-b0b6-df8c4c372e41')" layer: "SETTLED" units: "params.amount" currency: "'USD'" direction: DEBIT } ] } ) { code status } # Invalid CEL syntax in transaction.journalId tc2: createTranCode( input: { tranCodeId: "B852FEA6-3445-49E7-BFD4-A162EEC08018" code: "DEF456" description: "an example tran code" params: [{ name: "amount", type: DECIMAL }] transaction: { effective: "time.Now()" journalId: "822cb59f-ce51-4837-8391-2af3b7a5fc51" } entries: [ { entryType: "EXAMPLE" accountId: "uuid('7052f9fd-dd15-40d0-b0b6-df8c4c372e41')" layer: "SETTLED" units: "params.amount" currency: "'USD'" direction: DEBIT } ] } ) { code status } } ``` **Response** ```json { "errors": [ { "message": "input: tc1 [effective]: `{time.Now()}`, ERROR: :1:12: Syntax error: mismatched input '}' expecting ':'\n | {time.Now()}\n | ...........^", "path": ["tc1"], "extensions": { "code": "TRAN_CODE_ERROR", "retriableError": false } }, { "message": "input: tc2 [journal_id]: `822cb59f-ce51-4837-8391-2af3b7a5fc51`, ERROR: :1:4: Syntax error: mismatched input 'cb59f' expecting \n | 822cb59f-ce51-4837-8391-2af3b7a5fc51\n | ...^", "path": ["tc2"], "extensions": { "code": "TRAN_CODE_ERROR", "retriableError": false } } ], "data": null } ``` ### TRANSACTION_ERROR Indicates that there was an error with a transaction. ### UNIQUE_CONSTRAINT_VIOLATION Indicates that there was an error with a unique constraint. **Request** ```graphql mutation UNIQUE_CONSTRAINT_VIOLATION { # Account already exists createAccount( input: { accountId: "7052f9fd-dd15-40d0-b0b6-df8c4c372e41" code: "DUP_TESTACCT" name: "DUP_TESTACCT" normalBalanceType: DEBIT status: ACTIVE } ) { accountId } } ``` **Response** ```json { "errors": [ { "message": "input: createAccount unique constraint violation\nAccount.indexes.account_id unique constraint violation", "path": ["createAccount"], "extensions": { "action": "", "code": "UNIQUE_CONSTRAINT_VIOLATION", "path": "system.Account", "retriableError": false, "system": ["full_access_auth", "tx"] } } ], "data": null } ``` ### UNKNOWN_ERROR Indicates that an unknown error occurred. For example, an `unknown error` occuring when selecting accounts ```json { "errors": [ { "message": "input: accounts unknown error", "path": [ "accounts" ], "extensions": { "code": "UNKNOWN_ERROR", "retriableError": true } } ], "data": null } ``` ### UUID_PARSE_ERROR Indicates that there was an error parsing a UUID. **Request** ```graphql mutation INVALID_UUID_LENGTH { createAccount( input: { accountId: "" code: "TEST" name: "TEST" normalBalanceType: DEBIT status: ACTIVE } ) { accountId } } ``` **Response** ```json { "errors": [ { "message": "input: createAccount.input.accountId invalid UUID length: 0", "path": ["createAccount", "input", "accountId"], "extensions": { "code": "UUID_PARSE_ERROR", "retriableError": false } } ], "data": null } ``` --- # Extensions The Twisp GraphQL API supplies additional metadata about operations through the "extensions" subdocument. API responses may contain an `"extensions"` field in addition to the standard `"data"` field if certain request headers are specified. ## API Usage & Billing Billing stats about the current request may be returned within the `"extensions"` subdocument by including a `x-twisp-include-billing: true` header in the request. For example, here's is a response from invoking a bank transfer tran code with `postTransaction` and the `x-twisp-include-billing` HTTP header set to `true`: ```json { "data": { "postTransaction": { "transactionId": "5c328550-bba3-423b-a58a-b3f9786a80ad" }, }, "extensions": { "billing": { "duration": 229272730, "read": { "bytes": 5604, "count": 10, "units": 10 }, "write": { "bytes": 4850, "count": 16, "units": 16 } } } } ``` > **Note:** > > If using the gRPC apis the billing information will be emitted on the following trailer keys: > > > - billing-read-bytes > - billing-read-units > - billing-write-bytes > - billing-write-units > - billing-duration --- # API Requests via HTTPS Components of a GraphQL API request. All HTTPS requests (whether they are GraphQL [Queries](https://www.twisp.com/docs/reference/graphql/queries.md) or [Mutations](https://www.twisp.com/docs/reference/graphql/mutations.md)) are made using the `POST` method, with the GraphQL operation provided in the request body. > **Note:** > > For a step-by-step guide, see the [Making Api Requests With Curl](https://www.twisp.com/docs/tutorials/api/making-api-requests-with-curl.md) tutorial. When you are ready to start making requests to the Twisp API from your application code, the HTTPS request must include: - **URL**: the URL of the Twisp GraphQL API. - **Headers**: to authorize the request and specify content type. At minimum, these must include: - `authorization` with a bearer JWT - `x-twisp-account-id` for specifying the account ID to be used in the request - `content-type` set to `application/json` - ***Body**: the JSON-formatted GraphQL operation. Here is an example request for the first 10 accounts with a code starting with `BERT.`: ```shell curl 'https://api.us-east-1.cloud.twisp.com/financial/v1/graphql' \ -H 'authorization: Bearer ' \ -H 'content-type: application/json' \ -H 'x-twisp-account-id: ' \ --data-raw '{"query":"query { accounts(index:{name:CODE}, where:{code:{like:\"BERT.\"}},first:10) { nodes { accountId name code } } }"}' ``` The `` and `` are placeholders. If you created a [Tenant](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) named "Sandbox" with account ID `Sandbox0d6af983` and had a JWT encoded as `0cca9e8f` (obviously it would be much longer in actual usage), then you would replace `` with `Sandbox0d6af983` and `` with `0cca9e8f`. > **Note:** > > As you are first starting out with Twisp, we recommend using the GraphiQL interface in the Twisp console. It is a rich learning environment where you can focus on writing your GraphQL operations with built-in documentation and autocomplete. --- # API Reference Key components and concepts for interacting with the API. - [Requests](https://www.twisp.com/docs/reference/api/https-requests.md): Structure of the HTTP request. - [Response Format](https://www.twisp.com/docs/reference/api/response-format.md): Structure of the JSON response. - [Pagination](https://www.twisp.com/docs/reference/api/pagination.md): Cursor-based pagination for queries and fields. - [Errors](https://www.twisp.com/docs/reference/api/errors.md): Error codes returned by the API. - [Transactional Operations](https://www.twisp.com/docs/reference/api/transactional-operations.md): All-or-nothing semantics of API requests. - [Extensions](https://www.twisp.com/docs/reference/api/extensions.md): Metadata about API requests. - [Webhooks](https://www.twisp.com/docs/reference/api/webhooks.md): Signed HTTP notifications for record change events. --- # Indexes Queries against the ledger are done via database indexes. This document explains how to use them. --- # Pagination When making queries which can potentially return high-cardinality lists, the Twisp API supports cursor-based pagination. The Twisp GraphQL API implements a cursor-based pagination model using the [Relay GraphQL Cursor Connections Specification](https://relay.dev/graphql/connections.htm). This specification provides guidelines for making paginated requests using a concept called "Connections." Connections facilitate the process of fetching data in chunks (or pages) from a GraphQL API. > **Note:** > > For a step-by-step guide on using pagination in a GraphQL operation, see the [Querying Paginated Fields](https://www.twisp.com/docs/tutorials/api/querying-paginated-fields.md) tutorial. ## Heuristics for Paginated Queries Within the GraphQL schema, pluralized query fields (e.g. `Query.entries`, `Query.tranCodes`) return Connection types. No matter what type of record we query, the same pattern can be applied. You can use these basic heuristics across the schema: - When querying a field with a `*Connection` type response, you must indicate the number of records to return with the `first` argument. - To determine if there are additional records beyond the current page, query the `pageInfo` object. - To get the next page of `n` records, use the cursor provided `pageInfo.endCursor` as the `after` argument. - When there are no more records, `pageInfo.hasNextPage` will be false. This is an abstracted example of an imaginary `widgets` query to return `Widget` records: ```graphql query { widgets( after: "" # Cursor indicating the start point. first: 5 # Number of nodes (widgets) to return. ) { __typename # => WidgetConnection edges { __typename # => WidgetConnectionEdge cursor # Cursor position of the current edge. node { # The Widget record at this edge position. # ... # Field queries on the Widget record. } } nodes { # Alternate access to all `node` objects within `edges` __typename # => Widget # ... # Field queries on the Widget record. } pageInfo { hasPreviousPage # True if there are nodes in the connection before the current page / start cursor. hasNextPage # True if there are nodes in the connection after the current page / end cursor. startCursor # Query cursor for the first node in the current page. endCursor # Query cursor for the last node in the current page. } } } ``` The rest of this reference page will go into the specifics of cursor-based pagination using the `accounts` query as an example, but the same principles can be applied to every query resolving to a `*Connection` type. ## Querying Lists with the First Argument When making queries to fields which resolve to paginated lists of records, the required `first` argument is used to specify the _maximum_ number of records to return. For example, when using the `journals` query, we can request only the first 5 journals using the following query. We query the `nodes` field to get fields from the list of records returned. **Request** ```graphql query GetFirst5CustomerAccounts { journals( index: { name: CODE } where: { code: { like: "CUST." } } first: 5 ) { nodes { code } } } ``` **Response** ```json { "data": { "journals": { "nodes": [ { "code": "CUST.Armand" }, { "code": "CUST.Bradly" }, { "code": "CUST.Brittany" }, { "code": "CUST.Camila" }, { "code": "CUST.Carrie" } ] } } } ``` > **Note:** > > This example assumes a ledger structure where journals follow the `code` format of `CUST.`. Note also that the index used is automatically alphabetically sorted. ## Connections use PageInfo to Enable Pagination To query the nest page of records, we need to specify the **cursor position** to begin at by providing a value to the `after` argument of the query field. This tells the query to start at the cursor position and return the subsequent `n` records, where `n` is the number specified by the `first` argument. The `pageInfo` field returns a [PageInfo](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) object with the information needed to perform this kind of cursor-based pagination. It will tell us whether there are records (pages) **before** the `startCursor` of the current page and whether there are records (pages) **after** the `endCursor`. **Request** ```graphql query GetAccountsWithPageInfo { journals( index: { name: CODE } where: { code: { like: "CUST." } } first: 5 ) { nodes { code } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } ``` **Response** ```json { "data": { "journals": { "nodes": [ { "code": "CUST.Armand" }, { "code": "CUST.Bradly" }, { "code": "CUST.Brittany" }, { "code": "CUST.Camila" }, { "code": "CUST.Carrie" } ], "pageInfo": { "hasPreviousPage": false, "hasNextPage": true, "startCursor": "AN70l6_nkaCU5AFDVVNULkFybWFuZAABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "endCursor": "Ad70l6_nkaCU5AFDVVNULkNhcnJpZQABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg" } } } } ``` With this set of information, we have everything we need to write paginated queries. ## Querying with Cursors To make subsequent queries for additional pages of records, we use the cursor provided at `pageInfo.endCursor` from the current page as the `after` argument when querying the subsequent page. To simplify this procedure, let's imagine that there are 13 records that can be returned by a particular query, and we want to paginate using pages of 5 records each. We would need to perform three query operations: 1. To get the first page of 5 records, use `first: 5` while omitting the `after` argument to specify that we want to start our query at the beginning of the list. Query the `pageInfo.endCursor`. 2. To get the next page, use `first: 5` and `after: X` where `X` is the cursor returned in the first page's `pageInfo.endCursor`. 3. To get the final page, use `first: 5` and `after: Y` where `Y` is the cursor returned in the second page's `pageInfo.endCursor`. We can also render this 3-page query sequence as a table: | Page | After Cursor | Records (Nodes) | End Cursor | Next Page? | |------|--------------|-----------------|-----------------------------|------------| | `1` | `null` | `1..5` | `5b11e58c` (for record #5) | `TRUE` | | `2` | `5b11e58c` | `6..10` | `1b47d1e9` (for record #10) | `TRUE` | | `3` | `1b47d1e9` | `11..13` | `092e5914` (for record #13) | `FALSE` | Following up on the previous example using the `journals` query, we can use the `pageInfo.endCursor` from the first response as the `after` argument to get the next 5 journals: **Request** ```graphql query GetNext5Accounts { journals( index: { name: CODE } where: { code: { like: "CUST." } } first: 5 after: "Ad70l6_nkaCU5AFDVVNULkNhcnJpZQABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg" ) { nodes { code } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } ``` **Response** ```json { "data": { "journals": { "nodes": [ { "code": "CUST.Celestino" }, { "code": "CUST.Damion" }, { "code": "CUST.Eunice" }, { "code": "CUST.Jayde" }, { "code": "CUST.Martina" } ], "pageInfo": { "hasPreviousPage": true, "hasNextPage": true, "startCursor": "Ad70l6_nkaCU5AFDVVNULkNlbGVzdGlubwABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "endCursor": "Ad70l6_nkaCU5AFDVVNULk1hcnRpbmEAAQAAAP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8AASI" } } } } ``` ## Nodes and Edges Technically, every `*Connection` type returns a set of `edges` where each edge is identified by its `cursor` and contains a reference to a `node` which contains the record being queried (in this example, an [Account](https://www.twisp.com/docs/reference/graphql/types/object.md#account) object). The `nodes` field used in the above is simply a shorthand way of accessing all the `node` fields of every edge in the `edges` list. Similarly, the `startCursor` and `endCursor` fields from `pageInfo` are just shorthand ways to access the `cursor` of the first and last edge in the `edges` list, respectively. In the example below, the `journals` query returns an [JournalConnection](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection) type with an `edges` field containing a list of [JournalConnectionEdge](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection-edge) objects. Each [JournalConnectionEdge](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection-edge) object has a `cursor` position and a `node` referencing the [Journal](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) record. **Request** ```graphql query GetAccountEdgesWithCursor { journals( index: { name: CODE } where: { code: { like: "CUST." } } first: 5 after: "Ad70l6_nkaCU5AFDVVNULkNhcnJpZQABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg" ) { edges { cursor node { code } } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } } } ``` **Response** ```json { "data": { "journals": { "edges": [ { "cursor": "Ad70l6_nkaCU5AFDVVNULkNlbGVzdGlubwABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "node": { "code": "CUST.Celestino" } }, { "cursor": "Ad70l6_nkaCU5AFDVVNULkRhbWlvbgABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "node": { "code": "CUST.Damion" } }, { "cursor": "Ad70l6_nkaCU5AFDVVNULkV1bmljZQABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "node": { "code": "CUST.Eunice" } }, { "cursor": "Ad70l6_nkaCU5AFDVVNULkpheWRlAAEAAAD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AAEi", "node": { "code": "CUST.Jayde" } }, { "cursor": "Ad70l6_nkaCU5AFDVVNULk1hcnRpbmEAAQAAAP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8AASI", "node": { "code": "CUST.Martina" } } ], "pageInfo": { "hasPreviousPage": true, "hasNextPage": true, "startCursor": "Ad70l6_nkaCU5AFDVVNULkNlbGVzdGlubwABAAAA_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wABIg", "endCursor": "Ad70l6_nkaCU5AFDVVNULk1hcnRpbmEAAQAAAP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8A_wD_AP8AASI" } } } } ``` For most pagination queries, only the `nodes` field is needed. In the various examples shown in Twisp's documentation, we will usually omit `edges` and just query `nodes` to keep the response smaller and easier to read. ## Why Cursor-Based Pagination? The GraphQL core team has spent a lot more time on these questions than we have, and [they recommend opaque cursors as the best approach](https://graphql.org/learn/pagination/#pagination-and-edges). > In general, we've found that cursor-based pagination is the most powerful of those designed. There are other models out there, but for the GraphQL protocol this method provides the greatest combination of flexibility, specificity, and performance. --- # Response Format Requests to the Twisp GraphQL API return a consistent JSON response format. The API uses a response format conforming to the [GraphQL spec](https://spec.graphql.org/October2021/#sec-Response-Format). ``` { "data": { // GraphQL response } } ``` This means that every response is a JSON document with a `"data"` field. If the request produced an error, then it will also return an `"errors"` field. > The `data` entry in the response will be the result of the execution of the requested operation. If the operation was a query, this output will be an object of the query root operation type; if the operation was a mutation, this output will be an object of the mutation root operation type. > The `errors` entry in the response is a non-empty list of errors, where each error is a map. Because the Twisp API supports [Transactional Operations](https://www.twisp.com/docs/reference/api/transactional-operations.md), if there are _any_ errors, then the entire operation is aborted and the `"data"` field will be `null`. ``` { "errors": [ // list of errors ], "data": null } ``` In addition, responses may contain an `"extensions"` field if certain request headers are specified. Learn more about extensions in the [Extensions](https://www.twisp.com/docs/reference/api/extensions.md) reference. --- # Transactional Operations Requests to the GraphQL API are executed in a single transaction context with all-or-nothing semantics. Requests may contain multiple query or mutation operations. Every operation within a single request is executed within the same database transaction context, meaning that each operation will only succeed if _all_ operations succeed. In other words, if there is an error in any single operation, _none_ of the operations will succeed. Transactional database operations are useful because they help maintain data integrity, consistency, and reliability in applications that require complex operations or involve multiple data manipulation steps. For example, the following request includes two `postTransaction` mutations, but the second uses incorrect syntax that triggers a `JSON_PARSE_ERROR`. **Request** ```graphql mutation PostTXs { tx_1: postTransaction( input: { transactionId: "5c328550-bba3-423b-a58a-b3f9786a80ad" tranCode: "ACH_CREDIT" params: { account: "260fd651-8819-4f99-9c8a-87d27e03ee4c" amount: "10.25" effective: "2022-09-08" } } ) { transactionId } tx_2: postTransaction( input: { transactionId: "cd48f439-1f7b-40aa-9b95-4fcbbb51e3cf" tranCode: "ACH_CREDIT" params: { account: "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b" amount: "31.72" effective: "2022-09-09" } } ) { transactionId } } ``` **Response** ```json { "data": { "tx_1": { "transactionId": "5c328550-bba3-423b-a58a-b3f9786a80ad" }, "tx_2": { "transactionId": "cd48f439-1f7b-40aa-9b95-4fcbbb51e3cf" } } } ``` Note that the `"data"` field in the response is `null` because _neither_ transaction was posted. If we were to subsequently query for the first (valid) transaction, we would see that it was not posted. --- # Webhooks Subscribe to change events on ledger and ACH entities and receive them as signed HTTP requests. Webhooks deliver change events for records in your ledger to an HTTPS endpoint you control. Whenever a subscribed record is inserted, updated, or deleted, Twisp sends an HTTP `POST` to your endpoint with the new state of the record (and the previous state, when one exists). ## Creating an Endpoint Subscribe to events by creating an endpoint with the `createEndpoint` mutation: ```graphql mutation Setup { events { createEndpoint( input: { endpointId: "345940ed-2726-4b20-88aa-820857ac0e68" status: ENABLED endpointType: WEBHOOK url: "https://yourdomain.com/path/to/hooks" description: "subscribe to balance events" subscription: ["balance.*"] filters: { isMyCalcId: "document.calculation_id == uuid('5542ce2c-e43a-40b1-b04b-5dfb06f9f4d8')" } } ) { endpointId signingSecret } } } ``` - Replace `url` with your actual webhook URL. - Customize `subscription` to include the event types you are interested in. (`subscription: ["*"]` and `filters: {}` will get you the firehose.) - Save the returned `signingSecret` — you will need it to verify request signatures. See [EndpointInput](https://www.twisp.com/docs/reference/graphql/types/input.md#endpoint-input) for all configuration options. > **Note:** > > Webhooks work on the local version of Twisp too. ## Subscriptions Each subscription is a string in the format `.`, where action is one of `inserted`, `updated`, or `deleted`. Wildcards (`*`) are supported, so `balance.*` matches every balance event and `*` matches everything. Supported entities: - `journal` - `account` - `accountcontext` - `accountset` - `accountsetmember` - `trancode` - `transaction` - `entry` - `balance` - `customindex` - `custombalance` - `endpoint` - `kvvalue` — transactional key/value records Supported ACH entities: - `configuration` — ACH processing configurations - `fileinfo` — processing status of an ACH file - `filerecord` — individual records within an ACH file - `workflowtrace` — traces of ACH workflow execution For example, to track the processing status of ACH files, subscribe to `fileinfo.inserted` and `fileinfo.updated`. ## Filters The optional `filters` field is a map of named [CEL expressions](https://www.twisp.com/docs/reference/cel.md) evaluated against each candidate event. The record is available as `document`, with fields in `snake_case`. An event is sent only if _all_ expressions evaluate to `true` (they are combined with a logical AND). For example, to receive `transaction.inserted` events only for specific tran codes: ```graphql mutation CreateEvents($endpointId: UUID = "uuid.New()" @cel) { events { createEndpoint( input: { endpointId: $endpointId endpointType: WEBHOOK url: "https://yourdomain.com/path/to/hooks" subscription: ["transaction.inserted"] description: "Subscribe to ACH_SETTLE_CR and ACH_SETTLE_DR" filters: { isWorkflowSettle: "document.tran_code_id in [uuid('d918eb34-1ef9-4437-a82b-46c169f63e41'), uuid('5af51352-84ad-4534-aacf-4e68c2ed2e2b')]" } } ) { endpointId signingSecret } } } ``` ## Event Payload Events are delivered as a JSON document with the following envelope: | Field | Type | Description | | --------------- | --------- | ----------------------------------------------------------- | | `eventId` | UUID | Unique identifier for this event. | | `eventType` | String | The matched subscription, e.g. `balance.updated`. | | `accountId` | String | The Twisp tenant account id this event originated from. | | `region` | String | Region identifier this event originated from. | | `created` | Timestamp | When the event was created. | | `recordRowId` | UUID | Unique identifier of the record in `data`. | | `recordVersion` | Integer | Monotonically increasing version of the record. | | `data` | Object | The state of the record after the change. | | `previous` | Object | The state of the record before the change, when one exists. | Payloads use camelCase JSON keys. Timestamps, enumerations, dates, and UUIDs are represented as strings. Money values use an object with string `units` and `currency` fields. ## Payload Examples The examples below are generated from the linked protobuf messages and serialized with the same webhook formatter used by Twisp. They show inserted events, where `previous` is `null`; updated events include the prior record in `previous`. Twisp adds `version` to each serialized record. ### Journal Subscription: `journal.*`. Schema: [`twisp.core.v1.Journal`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Journal). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "journal.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "code": "EXAMPLE", "config": { "enableEffectiveBalances": true }, "created": "2026-08-26T18:00:00Z", "description": "Example record", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z", "name": "Example", "status": "ACTIVE", "version": 1 }, "previous": null } ``` ### Account Subscription: `account.*`. Schema: [`twisp.core.v1.Account`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Account). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "account.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68", "code": "EXAMPLE", "config": { "enableConcurrentPosting": true, "idempotent": false, "isAccountSet": false, "upsert": false }, "created": "2026-08-26T18:00:00Z", "description": "Example record", "externalId": "345940ed-2726-4b20-88aa-820857ac0e68", "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "name": "Example", "normalBalanceType": "CREDIT", "status": "ACTIVE", "version": 1 }, "previous": null } ``` ### Account context Subscription: `accountcontext.*`. Schema: [`twisp.core.v1.AccountContext`](https://github.com/twisp/core/blob/main/proto/private/twisp/core/v1/system.proto). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "accountcontext.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68", "created": "2026-08-26T18:00:00Z", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z", "parentAccounts": [ { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68" } ], "version": 1 }, "previous": null } ``` ### Account set Subscription: `accountset.*`. Schema: [`twisp.core.v1.AccountSet`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.AccountSet). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "accountset.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68", "accountSetId": "345940ed-2726-4b20-88aa-820857ac0e68", "code": "EXAMPLE", "config": { "enableConcurrentPosting": true, "idempotent": false, "upsert": false }, "created": "2026-08-26T18:00:00Z", "description": "Example record", "hasMembers": true, "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "name": "Example", "status": "ACTIVE", "version": 1 }, "previous": null } ``` ### Account set member Subscription: `accountsetmember.*`. Schema: [`twisp.core.v1.AccountSetMember`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.AccountSetMember). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "accountsetmember.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountSetId": "345940ed-2726-4b20-88aa-820857ac0e68", "created": "2026-08-26T18:00:00Z", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "memberId": "345940ed-2726-4b20-88aa-820857ac0e68", "memberType": "ACCOUNT", "version": 1 }, "previous": null } ``` ### Tran code Subscription: `trancode.*`. Schema: [`twisp.core.v1.TranCode`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.TranCode). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "trancode.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "assertions": { "key": "value" }, "code": "EXAMPLE", "created": "2026-08-26T18:00:00Z", "description": "Example record", "entries": [ { "accountId": "000000000000", "condition": "example", "currency": "USD", "description": "Example record", "direction": "example", "entryType": "EXAMPLE", "layer": "example", "metadata": "{'key': 'value'}", "units": "example" } ], "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "params": [ { "default": "example", "description": "Example record", "example": "example", "name": "Example", "type": "INT" } ], "status": "ACTIVE", "tranCodeId": "345940ed-2726-4b20-88aa-820857ac0e68", "transaction": { "correlationId": "345940ed-2726-4b20-88aa-820857ac0e68", "description": "Example record", "effective": "example", "externalId": "345940ed-2726-4b20-88aa-820857ac0e68", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "metadata": "{'key': 'value'}" }, "vars": { "key": "value" }, "version": 1, "workflow": { "executionId": "345940ed-2726-4b20-88aa-820857ac0e68", "params": { "example": "example" }, "task": "example", "workflowId": "345940ed-2726-4b20-88aa-820857ac0e68" } }, "previous": null } ``` ### Transaction Subscription: `transaction.*`. Schema: [`twisp.core.v1.Transaction`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Transaction). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "transaction.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "correlationId": "345940ed-2726-4b20-88aa-820857ac0e68", "created": "2026-08-26T18:00:00Z", "description": "Example record", "effective": "2026-08-26", "externalId": "345940ed-2726-4b20-88aa-820857ac0e68", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "properties": { "groups": [ "example" ], "overrideVelocityEnforcement": { "action": "VOID" } }, "tranCodeId": "345940ed-2726-4b20-88aa-820857ac0e68", "tranCodeVersion": 1, "transactionId": "345940ed-2726-4b20-88aa-820857ac0e68", "version": 1 }, "previous": null } ``` ### Entry Subscription: `entry.*`. Schema: [`twisp.core.v1.Entry`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Entry). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "entry.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68", "amount": { "currency": "USD", "units": "123.45" }, "balanceRecordId": "345940ed-2726-4b20-88aa-820857ac0e68", "balanceRecordVersion": 1, "committed": "2026-08-26T18:00:00Z", "created": "2026-08-26T18:00:00Z", "description": "Example record", "direction": "DEBIT", "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "entryType": "EXAMPLE", "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "layer": "SETTLED", "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "parentAccountIds": [ "345940ed-2726-4b20-88aa-820857ac0e68" ], "transactionId": "345940ed-2726-4b20-88aa-820857ac0e68", "transactionSeq": 1, "version": 1 }, "previous": null } ``` ### Balance Subscription: `balance.*`. Schema: [`twisp.core.v1.Balance`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Balance). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "balance.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "345940ed-2726-4b20-88aa-820857ac0e68", "availableEncumbrance": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "availablePending": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "availableSettled": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "calculationId": "345940ed-2726-4b20-88aa-820857ac0e68", "created": "2026-08-26T18:00:00Z", "currency": "USD", "dimension": "ZXhhbXBsZQ==", "dimensions": { "key": "value" }, "encumbrance": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "entryCommitted": "2026-08-26T18:00:00Z", "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "entryTimestamps": [ 1 ], "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z", "pending": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "settled": { "crBalance": { "currency": "USD", "units": "123.45" }, "drBalance": { "currency": "USD", "units": "123.45" }, "entryId": "345940ed-2726-4b20-88aa-820857ac0e68", "modified": "2026-08-26T18:00:00Z" }, "transactionId": "345940ed-2726-4b20-88aa-820857ac0e68", "version": 1 }, "previous": null } ``` ### Custom index Subscription: `customindex.*`. Schema: [`twisp.db.v1.CustomIndex`](https://github.com/twisp/core/blob/main/proto/private/twisp/db/v1/custom_index.proto). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "customindex.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "id": "ZXhhbXBsZQ==", "index": { "filters": { "example": "example" }, "id": "ZXhhbXBsZQ==", "partition": [ { "alias": "example", "order": "DESC", "type": "INT", "value": "example" } ], "properties": { "asynchronous": false, "buckets": 1, "external": false, "historical": false, "nonCartesian": false, "system": false, "unique": false }, "referencedBy": [ "example" ], "schema": { "key": "value" }, "sort": [ { "alias": "example", "order": "DESC", "type": "INT", "value": "example" } ], "state": "DELETE_ONLY" }, "name": "Example", "on": "Account", "synchronization": "SYNCHRONOUS", "version": 1, "viewName": "Example" }, "previous": null } ``` ### Custom balance Subscription: `custombalance.*`. Schema: [`twisp.core.v1.Calculation`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Calculation). Custom balance records use the `Calculation` protobuf message. ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "custombalance.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "backfillStatus": "IN_PROGRESS", "calculationId": "345940ed-2726-4b20-88aa-820857ac0e68", "code": "EXAMPLE", "condition": "example", "config": { "effectiveDateSource": "example", "effectiveGranularity": "YEAR", "enableEffectiveBalances": true, "parentCalculationId": "345940ed-2726-4b20-88aa-820857ac0e68" }, "created": "2026-08-26T18:00:00Z", "description": "Example record", "dimensions": [ { "alias": "example", "type": "INT", "value": "example" } ], "modified": "2026-08-26T18:00:00Z", "scope": "GLOBAL", "skipCalculation": false, "status": "ACTIVE", "version": 1 }, "previous": null } ``` ### Endpoint Subscription: `endpoint.*`. Schema: [`twisp.core.v1.Endpoint`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.Endpoint). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "endpoint.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "accountId": "000000000000", "created": "2026-08-26T18:00:00Z", "description": "Example record", "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "endpointType": "WEBHOOK", "filters": { "example": "example" }, "modified": "2026-08-26T18:00:00Z", "signingSecret": "whsec_example", "status": "ENABLED", "subscription": [ "balance.*" ], "url": "https://yourdomain.com/path/to/hooks", "version": 1 }, "previous": null } ``` ### Key/value record Subscription: `kvvalue.*`. Schema: [`twisp.core.v1.KVValue`](https://buf.build/twisp/api/docs/main:twisp.core.v1#twisp.core.v1.KVValue). Key/value records use the `KVValue` protobuf message. ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "kvvalue.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "conditions": { "example": "example" }, "created": "2026-08-26T18:00:00Z", "description": "Example record", "key": "customer-123", "modified": "2026-08-26T18:00:00Z", "namespace": "customers", "value": { "key": "value" }, "version": 1 }, "previous": null } ``` ### ACH configuration Subscription: `configuration.*`. Schema: [`twisp.ach.v1.Configuration`](https://buf.build/twisp/api/docs/main:twisp.ach.v1#twisp.ach.v1.Configuration). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "configuration.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "autoPending": false, "configurationId": "345940ed-2726-4b20-88aa-820857ac0e68", "direction": "BOTH", "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "exceptionAccountId": "345940ed-2726-4b20-88aa-820857ac0e68", "feeAccountId": "345940ed-2726-4b20-88aa-820857ac0e68", "fileModifierConfiguration": { "endFileIdModifier": "example", "startFileIdModifier": "example", "userSupplied": false }, "journalId": "345940ed-2726-4b20-88aa-820857ac0e68", "lastFileDate": "2026-08-26T18:00:00Z", "lastFileIdModifier": "example", "lastTraceNumber": 1, "odfiBatchHeader": { "enableBalancedReturnNocs": true, "includeOffset": false, "offsetAccountNumber": "example", "offsetAccountType": "EXAMPLE", "offsetDescription": "Example record", "offsetRoutingNumber": "example" }, "odfiFileHeader": { "immediateDestination": "example", "immediateDestinationName": "Example", "immediateOrigin": "example", "immediateOriginName": "Example" }, "pendingAccountId": "345940ed-2726-4b20-88aa-820857ac0e68", "settlementAccountId": "345940ed-2726-4b20-88aa-820857ac0e68", "suspenseAccountId": "345940ed-2726-4b20-88aa-820857ac0e68", "timeZone": "example", "traceNumberConfiguration": { "maxTraceNumber": 1, "minTraceNumber": 1 }, "usedFileIdModifiers": 1, "version": 1 }, "previous": null } ``` ### ACH file info Subscription: `fileinfo.*`. Schema: [`twisp.ach.v1.FileInfo`](https://buf.build/twisp/api/docs/main:twisp.ach.v1#twisp.ach.v1.FileInfo). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "fileinfo.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "configId": "345940ed-2726-4b20-88aa-820857ac0e68", "configVersion": 1, "created": "2026-08-26T18:00:00Z", "fileDateTime": "example", "fileId": "345940ed-2726-4b20-88aa-820857ac0e68", "fileKey": "example", "fileModifier": "example", "fileVersion": "example", "hasExceptions": true, "metadata": { "key": "value" }, "modified": "2026-08-26T18:00:00Z", "processingDetail": "example", "processingStatistics": { "numEntriesUnprocessed": 1, "totalCreditAmount": "example", "totalDebitAmount": "example" }, "processingStatus": "VALIDATING", "processingType": "RDFI", "version": 1 }, "previous": null } ``` ### ACH file record Subscription: `filerecord.*`. Schema: [`twisp.ach.v1.FileRecord`](https://buf.build/twisp/api/docs/main:twisp.ach.v1#twisp.ach.v1.FileRecord). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "filerecord.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "Value": { "file": { "advControl": { "batchCount": 1, "blockCount": 1, "entryAddendaCount": 1, "entryHash": 1, "lineNumber": 1, "totalCreditEntryDollarAmountInFile": 1, "totalDebitEntryDollarAmountInFile": 1 }, "batches": [ { "advControl": { "achOperatorData": "example", "batchNumber": 1, "entryAddendaCount": 1, "entryHash": 1, "lineNumber": 1, "odfiIdentification": "example", "serviceClassCode": 1, "totalCreditEntryDollarAmount": 1, "totalDebitEntryDollarAmount": 1 }, "advEntries": [ { "achOperatorData": "example", "achOperatorRoutingNumber": "example", "addendaRecordIndicator": 1, "adviceRoutingNumber": "example", "amount": 1, "category": "example", "checkDigit": "example", "dfiAccountNumber": "example", "discretionaryData": "example", "fileIdentification": "example", "individualName": "Example", "julianDay": 1, "lineNumber": 1, "rdfiIdentification": "example", "sequenceNumber": 1, "transactionCode": 1 } ], "category": "example", "control": { "batchNumber": 1, "companyIdentification": "example", "entryAddendaCount": 1, "entryHash": 1, "lineNumber": 1, "messageAuthenticationCode": "EXAMPLE", "odfiIdentification": "example", "serviceClassCode": 1, "totalCreditEntryDollarAmount": 1, "totalDebitEntryDollarAmount": 1 }, "entries": [ { "addendaRecordIndicator": 1, "amount": 1, "category": "example", "checkDigit": "example", "dfiAccountNumber": "example", "discretionaryData": "example", "identificationNumber": "example", "individualName": "Example", "lineNumber": 1, "rdfiIdentification": "example", "traceNumber": "example", "transactionCode": 1 } ], "header": { "batchNumber": 1, "companyDescriptiveDate": "example", "companyDiscretionaryData": "example", "companyEntryDescription": "Example record", "companyIdentification": "example", "companyName": "Example", "effectiveEntryDate": "example", "lineNumber": 1, "odfiIdentification": "example", "originatorStatusCode": 1, "serviceClassCode": 1, "settlementDate": "example", "standardEntryClassCode": "EXAMPLE" }, "offset": { "accountNumber": "example", "accountType": "EXAMPLE", "description": "Example record", "routingNumber": "example" } } ], "control": { "batchCount": 1, "blockCount": 1, "entryAddendaCount": 1, "entryHash": 1, "lineNumber": 1, "totalCreditEntryDollarAmountInFile": 1, "totalDebitEntryDollarAmountInFile": 1 }, "header": { "blockingFactor": "example", "fileCreationDate": "example", "fileCreationTime": "example", "fileIdModifier": "example", "formatCode": "EXAMPLE", "immediateDestination": "example", "immediateDestinationName": "Example", "immediateOrigin": "example", "immediateOriginName": "Example", "lineNumber": 1, "priorityCode": "EXAMPLE", "recordSize": "example", "referenceCode": "EXAMPLE" }, "iatBatches": [ { "category": "example", "control": { "batchNumber": 1, "companyIdentification": "example", "entryAddendaCount": 1, "entryHash": 1, "lineNumber": 1, "messageAuthenticationCode": "EXAMPLE", "odfiIdentification": "example", "serviceClassCode": 1, "totalCreditEntryDollarAmount": 1, "totalDebitEntryDollarAmount": 1 }, "entries": [ { "addendaRecordIndicator": 1, "addendaRecords": 1, "amount": 1, "category": "example", "checkDigit": "example", "dfiAccountNumber": "example", "lineNumber": 1, "ofacScreeningIndicator": "example", "rdfiIdentification": "example", "secondaryOfacScreeningIndicator": "example", "traceNumber": "example", "transactionCode": 1 } ], "header": { "batchNumber": 1, "companyEntryDescription": "Example record", "effectiveEntryDate": "example", "foreignExchangeIndicator": "example", "foreignExchangeReference": "example", "foreignExchangeReferenceIndicator": 1, "iatIndicator": "example", "isoDestinationCountryCode": "EXAMPLE", "isoDestinationCurrencyCode": "USD", "isoOriginatingCurrencyCode": "USD", "lineNumber": 1, "odfiIdentification": "example", "originatorIdentification": "example", "originatorStatusCode": 1, "serviceClassCode": 1, "settlementDate": "example", "standardEntryClassCode": "EXAMPLE" } } ] } }, "batchCount": 1, "batchPosition": 1, "created": "2026-08-26T18:00:00Z", "entryCount": 1, "entryPosition": 1, "fileId": "345940ed-2726-4b20-88aa-820857ac0e68", "fileKey": "example", "recordCount": 1, "recordId": "345940ed-2726-4b20-88aa-820857ac0e68", "recordPosition": 1, "recordType": "FILE", "version": 1 }, "previous": null } ``` ### ACH workflow trace Subscription: `workflowtrace.*`. Schema: [`twisp.ach.v1.WorkflowTrace`](https://buf.build/twisp/api/docs/main:twisp.ach.v1#twisp.ach.v1.WorkflowTrace). ```json { "eventId": "3f6e9283-5d96-546e-87db-3bf3c7d29011", "eventType": "workflowtrace.inserted", "accountId": "000000000000", "region": "us-west-2", "created": "2026-08-26T18:00:00Z", "recordRowId": "0198af4c-ffcc-44e6-bdcb-5567ba61a9e4", "recordVersion": 1, "data": { "configId": "345940ed-2726-4b20-88aa-820857ac0e68", "executionId": "345940ed-2726-4b20-88aa-820857ac0e68", "executionVersion": 1, "fileId": "345940ed-2726-4b20-88aa-820857ac0e68", "recordId": "345940ed-2726-4b20-88aa-820857ac0e68", "traceNumber": "example", "version": 1, "workflowId": "345940ed-2726-4b20-88aa-820857ac0e68" }, "previous": null } ``` ## Verifying Requests Every webhook request includes two headers: | Header | Description | | -------------------- | -------------------------------------------------------------- | | `x-twisp-signature` | HMAC SHA-256 signature of the request body, hex encoded. | | `x-twisp-account-id` | The Twisp tenant account identifier the event originated from. | To validate that a request is authentic, recreate the signature with your endpoint's `signingSecret` and the raw request body, then compare it against the `x-twisp-signature` header. Reject any request where the signatures don't match. ```go import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "net/http" ) func validateRequest(r *http.Request, body []byte, signingSecret string) bool { signature := r.Header.Get("x-twisp-signature") mac := hmac.New(sha256.New, []byte(signingSecret)) mac.Write(body) expectedSignature := hex.EncodeToString(mac.Sum(nil)) return hmac.Equal([]byte(signature), []byte(expectedSignature)) } ``` ## Delivery and Retries Twisp sends an event to every endpoint whose subscription and filters match. If your endpoint responds with a `2XX` HTTP status code, the delivery is considered successful. On any other status code or connection error, Twisp retries the request every 471 seconds for up to 24 hours (roughly 185 attempts). Design your handler to be idempotent — use `eventId` to deduplicate, or `recordRowId` and `recordVersion` to detect out-of-order or duplicate deliveries. --- # CEL Function Examples Example usage of nearly all CEL functions in Twisp runtime. Twisp pervasively uses [Common Expression Language](https://cel.dev/) for computation across many apis: 1. Index Value and Filtering Definitions 2. Security Policy Conditions 3. Webhook Filters 4. Calculations 5. Velocity Controls 6. Tran Codes In addition to the standard CEL library, Twisp exposes a number of custom functions that you might find useful as you build your core accounting system. On this page you can find extensive executable examples you can use to discover what the CEL functions can do for you. ## Constructors & Conversions These functions allow you to create instances of specific data types or convert values between different types. This is essential for manipulating data within CEL expressions effectively. ### Bool Converts a string ("true" or "false") to a boolean value. ```graphql # func bool(bool) bool # func bool(string) bool mutation BoolConversion { evaluate( expressions: { fromStringTrue: "bool('true')" # true fromStringFalse: "bool('false')" # false } ) } ``` ### Bytes Converts strings or UUIDs into byte sequences. Useful for hashing or encoding functions. ```graphql # func bytes(bytes) bytes # func bytes(string) bytes # func bytes(twisp.type.v1.UUID) bytes mutation BytesConversion { evaluate( expressions: { fromString: "string(bytes('hello'))" # Should show bytes representation or convert back for check: "hello" fromUuid: "hex.EncodeToString(bytes(uuid('123e4567-e89b-12d3-a456-426614174000')))" # Hex of UUID bytes: "123e4567e89b12d3a456426614174000" } ) } ``` ### Date Constructs a Date object from a string (YYYY-MM-DD format) or a Timestamp. ```graphql # func date(twisp.type.v1.Date) twisp.type.v1.Date # func date(google.protobuf.Timestamp) twisp.type.v1.Date # func date(string) twisp.type.v1.Date mutation DateConversion { evaluate( expressions: { fromString: "string(date('2023-10-27'))" # "2023-10-27" fromTimestamp: "string(date(timestamp('2023-10-27T15:00:00Z')))" # "2023-10-27" } ) } ``` ### Decimal Constructs a high-precision Decimal object from a string representation or converts a Money object to its Decimal value. ```graphql # func decimal(twisp.type.v1.Decimal) twisp.type.v1.Decimal # func decimal(twisp.type.v1.Money) twisp.type.v1.Decimal # func decimal(string) twisp.type.v1.Decimal # func (twisp.type.v1.Money) decimal() twisp.type.v1.Decimal mutation DecimalConversion { evaluate( expressions: { fromString: "string(decimal('123.456'))" # "123.456" fromMoney: "string(decimal(money('99.99', 'USD')))" # "99.99" fromMoneyMethod: "string(money('50.00', 'EUR').decimal())" # "50.00" } ) } ``` ### Double Converts integer, unsigned integer, or string representations to a double-precision floating-point number. ```graphql # func double(double) double # func double(int) double # func double(string) double # func double(uint) double mutation DoubleConversion { evaluate( expressions: { fromInt: "double(5)" # 5.0 fromString: "double('3.14')" # 3.14 fromUint: "double(10u)" # 10.0 } ) } ``` ### Duration Constructs a Duration object from a string representation (e.g., "1h30m15s"). ```graphql # func duration(google.protobuf.Duration) google.protobuf.Duration # func duration(int) google.protobuf.Duration # func duration(string) google.protobuf.Duration mutation DurationConversion { evaluate( expressions: { fromString: "string(duration('1h30m15s'))" # "5415s" (canonical string representation) } ) } ``` ### Dyn Converts a value to a dynamic type, useful for functions accepting heterogeneous lists or for working with JSON-like structures. ```graphql # func dyn(A) dyn mutation DynExample { evaluate(expressions: { result: "dyn('hello') == dyn('hello')" }) # Example: true (demonstrates dyn conversion and comparison) } ``` ### Int Converts various types (double, duration, string, timestamp, uint) to an integer. Note that conversion from double truncates the decimal part. Timestamps convert to epoch seconds, durations to total seconds. ```graphql # func int(int) int # func int(double) int # func int(google.protobuf.Duration) int # func int(string) int # func int(google.protobuf.Timestamp) int # func int(uint) int mutation IntConversion { evaluate( expressions: { fromDouble: "int(3.9)" # 3 (truncates) fromString: "int('123')" # 123 fromUint: "int(100u)" # 100 fromTimestamp: "int(timestamp(0))" # 0 (epoch seconds) fromDuration: "int(duration('60s'))" # 60 (total seconds) } ) } ``` ### Money Constructs a Money object, typically requiring an amount (as string, decimal, or int) and a currency code string. ```graphql # func money(twisp.type.v1.Money) twisp.type.v1.Money # func money(string, string) twisp.type.v1.Money # func money(twisp.type.v1.Decimal, string) twisp.type.v1.Money # func money(int, string) twisp.type.v1.Money mutation MoneyConversion { evaluate( expressions: { fromString: "money('123.45', 'USD')" # "123.45 USD" fromDecimal: "money(decimal('99.99'), 'EUR')" # "99.99 EUR" fromInt: "money(100, 'JPY')" # "100 JPY" (no decimals for JPY often) } ) } ``` ### String Converts various data types (boolean, bytes, double, duration, int, timestamp, uint, date, decimal, UUID) into their string representation. ```graphql # func string(string) string # func string(bool) string # func string(bytes) string # func string(double) string # func string(google.protobuf.Duration) string # func string(int) string # func string(google.protobuf.Timestamp) string # func string(uint) string # func string(twisp.type.v1.Date) string # func string(twisp.type.v1.Decimal) string # func string(twisp.type.v1.UUID) string mutation StringConversion { evaluate( expressions: { fromBool: "string(true)" # "true" fromBytes: "string(b'hello')" # "hello" fromDouble: "string(3.14)" # "3.14" fromDuration: "string(duration('1m'))" # "60s" or similar fromInt: "string(123)" # "123" fromTimestamp: "string(timestamp(0))" # "1970-01-01T00:00:00Z" fromUint: "string(10u)" # "10" fromDecimal: "string(decimal('1.2'))" # "1.2" fromUuid: "string(uuid.New())" # Example: "a1b2c3d4-..." } ) } ``` ### Timestamp Constructs a Timestamp object from a string (RFC3339 format) or an integer (interpreted as epoch seconds or milliseconds, depending on implementation). ```graphql # func timestamp(google.protobuf.Timestamp) google.protobuf.Timestamp # func timestamp(int) google.protobuf.Timestamp # func timestamp(string) google.protobuf.Timestamp mutation TimestampConversion { evaluate( expressions: { fromString: "string(timestamp('2023-10-27T12:00:00Z'))" # "2023-10-27T12:00:00Z" fromEpoch: "string(timestamp(1678886400))" # Interpreted as epoch seconds: "2023-03-15T13:20:00Z" } ) } ``` ### Type Returns the type of a given value. Useful for introspection or conditional logic based on type. ```graphql # func type(A) type(A) mutation TypeExample { evaluate( expressions: { intType: "type(123) == int" # true stringType: "type('abc') == string" # true } ) } ``` ### Uint Converts double, integer, or string representations to an unsigned integer. Conversion from double truncates. ```graphql # func uint(uint) uint # func uint(double) uint # func uint(int) uint # func uint(string) uint mutation UintConversion { evaluate( expressions: { fromDouble: "uint(3.9)" # 3u (truncates) fromString: "uint('123')" # 123u fromInt: "uint(100)" # 100u } ) } ``` ### UUID Constructs a UUID object from its string or byte representation. ```graphql # func uuid(twisp.type.v1.UUID) twisp.type.v1.UUID # func uuid(string) twisp.type.v1.UUID # func uuid(bytes) twisp.type.v1.UUID mutation UuidConversion { evaluate( expressions: { fromString: "string(uuid('123e4567-e89b-12d3-a456-426614174000'))" # "123e4567-e89b-12d3-a456-426614174000" fromBytes: "string(uuid(b'\\x12>Eg\\xe8\\x9b\\x12\\xd3\\xa4VBC\\x14\\x17@\\x00'))" # "123e4567-e89b-12d3-a456-426614174000" } ) } ``` ## Operators CEL supports common operators for arithmetic, comparison, logic, and collection access. ### Arithmetic Operators #### Addition / Concatenation (+) Performs addition for numeric types (int, double, decimal, money) and duration/timestamp combinations. Concatenates strings, bytes, and lists. ```graphql # func _+_(...) (Addition/Concatenation Operator) mutation AddOperator { evaluate( expressions: { int: "5 + 3" # 8 double: "1.5 + 2.5" # 4.0 string: "'hello' + ' ' + 'world'" # "hello world" list: "[1, 2] + [3, 4]" # [1, 2, 3, 4] timestampDuration: "string(timestamp('2023-01-01T00:00:00Z') + duration('24h'))" # "2023-01-02T00:00:00Z" durationDuration: "string(duration('1h') + duration('30m'))" # "5400s" or "1h30m" decimal: "string(decimal('1.1') + decimal('2.2'))" # "3.3" } ) } ``` #### Subtraction (-) Performs subtraction for numeric types (int, double, decimal, money), duration/timestamp combinations, and between two timestamps (resulting in a duration). ```graphql # func _-_(...) (Subtraction Operator) mutation SubtractOperator { evaluate( expressions: { int: "10 - 3" # 7 double: "5.5 - 1.5" # 4.0 timestampDuration: "string(timestamp('2023-01-02T00:00:00Z') - duration('24h'))" # "2023-01-01T00:00:00Z" timestampTimestamp: "string(timestamp('2023-01-02T00:00:00Z') - timestamp('2023-01-01T00:00:00Z'))" # "86400s" or "24h" durationDuration: "string(duration('1h') - duration('15m'))" # "2700s" or "45m" decimal: "string(decimal('3.3') - decimal('1.1'))" # "2.2" } ) } ``` #### Multiplication (*) Performs multiplication for numeric types (int, uint, double, decimal). ```graphql # func _*_(double, double) double # func _*_(int, int) int # func _*_(uint, uint) uint (Multiplication Operator) mutation MultiplicationOperator { evaluate( expressions: { int: "5 * 3" # 15 uint: "5u * 3u" # 15u double: "1.5 * 2.0" # 3.0 # decimal: decimal('1.5') * decimal('2') # decimal('3.0') } ) } ``` #### Division (/) Performs division for numeric types (int, uint, double, decimal). Integer and uint division truncates towards zero. ```graphql # func _/_(double, double) double # func _/_(int, int) int # func _/_(uint, uint) uint (Division Operator) mutation DivisionOperator { evaluate( expressions: { int: "10 / 3" # 3 (integer division) uint: "10u / 3u" # 3u double: "10.0 / 4.0" # 2.5 # decimal: decimal('10') / decimal('4') # decimal('2.5') } ) } ``` #### Modulo (%) Calculates the remainder of integer or unsigned integer division. ```graphql # func _%_(int, int) int # func _%_(uint, uint) uint (Modulo Operator) mutation ModuloOperator { evaluate( expressions: { int: "10 % 3" # 1 uint: "10u % 3u" # 1u } ) } ``` #### Unary Negation (-) Negates an integer or double value. ```graphql # func -_(double) double # func -_(int) int (Unary Negation) mutation UnaryNegation { evaluate( expressions: { int: "-5" # -5 double: "-3.14" # -3.14 } ) } ``` ### Comparison Operators These operators compare two values and return a boolean result. They work across various compatible types (numbers, strings, timestamps, durations, decimals, money, bytes). #### Equality (==) Checks if two values are equal. For lists and maps, this typically performs a deep equality check. ```graphql # func _==_(A, A) bool (Equality Operator) mutation EqualityOperator { evaluate( expressions: { int: "5 == 5" # true string: "'hello' == 'hello'" # true bool: "true == !false" # true list: "[1, 2] == [1, 2]" # true (usually deep equality) } ) } ``` #### Inequality (!=) Checks if two values are not equal. ```graphql # func _!=_(A, A) bool (Inequality Operator) mutation InequalityOperator { evaluate( expressions: { int: "5 != 10" # true string: "'hello' != 'world'" # true list: "[1] != [2]" # true } ) } ``` #### Less Than (<) Checks if the left operand is strictly less than the right operand. ```graphql # func _<_(...) bool (Comparison Operator) mutation LessThanOperator { evaluate( expressions: { int: "5 < 10" # true double: "3.14 < 3.15" # true string: "'apple' < 'banana'" # true timestamp: "timestamp('2023-01-01T00:00:00Z') < timestamp('2023-01-02T00:00:00Z')" # true decimal: "decimal('1.2') < decimal('1.3')" # true } ) } ``` #### Less Than or Equal (<=) Checks if the left operand is less than or equal to the right operand. ```graphql # func _<=_(...) bool (Less Than or Equal Operator) mutation LessThanOrEqualOperator { evaluate( expressions: { int: "5 <= 5" # true double: "3.14 <= 3.14" # true string: "'apple' <= 'apple'" # true } ) } ``` #### Greater Than (>) Checks if the left operand is strictly greater than the right operand. ```graphql # func _>_(...) bool (Greater Than Operator) mutation GreaterThanOperator { evaluate( expressions: { int: "10 > 5" # true double: "3.15 > 3.14" # true string: "'banana' > 'apple'" # true decimal: "decimal('1.3') > decimal('1.2')" # true } ) } ``` #### Greater Than or Equal (>=) Checks if the left operand is greater than or equal to the right operand. ```graphql # func _>=_(...) bool (Greater Than or Equal Operator) mutation GreaterThanOrEqualOperator { evaluate( expressions: { int: "5 >= 5" # true double: "3.15 >= 3.14" # true string: "'b' >= 'a'" # true } ) } ``` ### Logical Operators #### Logical AND (&&) Returns true if both boolean operands are true, otherwise false. Short-circuits (does not evaluate the right operand if the left is false). ```graphql # func _&&_(bool, bool) bool (Logical AND) mutation LogicalAnd { evaluate(expressions: { result: "true && (1 < 2)" }) # Example: true } ``` #### Logical OR (||) Returns true if at least one boolean operand is true, otherwise false. Short-circuits (does not evaluate the right operand if the left is true). ```graphql # func _||_(bool, bool) bool (Logical OR) mutation LogicalOr { evaluate(expressions: { result: "false || (1 < 2)" }) # Example: true } ``` #### Logical NOT (!) Inverts a boolean value (true becomes false, false becomes true). ```graphql # func !_(bool) bool (Logical NOT) mutation LogicalNot { evaluate(expressions: { result: "!false" }) # Example: true } ``` ### Conditional (Ternary) Operator (?:) Evaluates a boolean condition. If true, returns the second operand; if false, returns the third operand. ```graphql # func _?_:_(bool, A, A) A mutation TernaryOperator { evaluate(expressions: { result: "true ? 'yes' : 'no'" }) # Example: "yes" } ``` ### Collection Operators #### In Operator (in) Checks for membership. For lists, it checks if an element exists. For maps, it checks if a key exists. `@in` and `_in_` are alternative syntaxes. ```graphql # func @in(A, list(A)) bool # func in(A, list(A)) bool # func _in_(A, list(A)) bool mutation InOperatorList { evaluate(expressions: { result: "2 in [1, 2, 3]" }) # Example: true } # func @in(A, map(A, B)) bool # func in(A, map(A, B)) bool # func _in_(A, map(A, B)) bool mutation InOperatorMap { evaluate(expressions: { result: "'b' in {'a': 1, 'b': 2}" }) # Example: true (checks for key existence) } ``` #### Index Operator ([]) Accesses elements in lists by integer index or values in maps by key. Also works on optional lists/maps, returning an optional value. Accessing out-of-bounds index or non-existent key results in an error unless used on an optional type. ```graphql # func _[_](list(A), int) A mutation ListIndex { evaluate(expressions: { result: "[10, 20, 30][1]" }) # Example: 20 } # func _[_](map(A, B), A) B mutation MapIndex { evaluate(expressions: { result: "{'a': 1, 'b': 2}['a']" }) # Example: 1 } # func _[_](optional_type(list(V)), int) optional_type(V) mutation OptionalListIndex { evaluate( expressions: { present: "optional.of([10, 20])[0].value()" # 10 absent: "optional.of([10, 20])[2].hasValue()" # false (index out of bounds returns empty optional) } ) } # func _[_](optional_type(map(K, V)), K) optional_type(V) mutation OptionalMapIndex { evaluate( expressions: { present: "optional.of({'a': 1})['a'].value()" # 1 absent: "optional.of({'a': 1})['b'].hasValue()" # false (key not found returns empty optional) } ) } ``` #### Safe Index Operator ([?]) Accesses elements in lists or maps like the standard index operator, but *always* returns an optional type. Returns an empty optional instead of an error for out-of-bounds indices or non-existent keys. Works on both regular and optional collections. ```graphql # func _[?_](list(V), int) optional_type(V) mutation SafeListIndexPresent { evaluate(expressions: { result: "[10, 20][?0].value()" }) # Example: 10 } mutation SafeListIndexAbsent { evaluate(expressions: { result: "[10, 20][?2].hasValue()" }) # Example: false } # func _[?_](optional_type(list(V)), int) optional_type(V) mutation SafeOptionalListIndex { evaluate( expressions: { present: "optional.of([10, 20])[?0].value()" # 10 absentIndex: "optional.of([10, 20])[?2].hasValue()" # false absentList: "optional.none()[?0].hasValue()" # false } ) } # func _[?_](map(K, V), K) optional_type(V) mutation SafeMapIndexPresent { evaluate(expressions: { result: "{'a': 1}[?'a'].value()" }) # Example: 1 } mutation SafeMapIndexAbsent { evaluate(expressions: { result: "{'a': 1}[?'b'].hasValue()" }) # Example: false } # func _[?_](optional_type(map(K, V)), K) optional_type(V) mutation SafeOptionalMapIndex { evaluate( expressions: { present: "optional.of({'a': 1})[?'a'].value()" # 1 absentKey: "optional.of({'a': 1})[?'b'].hasValue()" # false absentMap: "optional.none()[?'a'].hasValue()" # false } ) } ``` #### Optional Field Access (.?) Safely accesses fields on dynamic types (`dyn`). If the field exists, it returns an optional containing the field's value. If the field does not exist, it returns an empty optional instead of an error. ```graphql # func _?._(dyn, string) optional_type(V) mutation OptionalFieldAccess { evaluate( expressions: { present: "dyn({'a': 1}).?a.value()" # 1 absent: "dyn({'a': 1}).?b.hasValue()" # false } ) } ``` ## Optional Type Helpers Functions for creating and working with optional types, which represent values that may or may not be present. ### optional.of Creates an optional containing the given value. ```graphql # func optional.of(V) optional_type(V) mutation OptionalOf { evaluate(expressions: { result: "optional.of('value').value()" }) # Example: "value" } ``` ### optional.none Creates an empty optional (representing no value). ```graphql # func optional.none() optional_type(V) mutation OptionalNone { evaluate(expressions: { result: "optional.none().hasValue()" }) # Example: false } ``` ### optional.ofNonZeroValue Creates an optional containing the value if it's not the zero-value for its type (e.g., not 0 for int, not "" for string, not false for bool). Otherwise, creates an empty optional. ```graphql # func optional.ofNonZeroValue(V) optional_type(V) mutation OptionalOfNonZeroValueInt { evaluate( expressions: { zero: "optional.ofNonZeroValue(0).hasValue()" # false nonZero: "optional.ofNonZeroValue(5).hasValue()" # true } ) } mutation OptionalOfNonZeroValueString { evaluate( expressions: { empty: "optional.ofNonZeroValue('').hasValue()" # false nonEmpty: "optional.ofNonZeroValue('hello').hasValue()" # true } ) } ``` ### (optional) hasValue Checks if the optional contains a value (returns true) or is empty (returns false). ```graphql # func (optional_type(V)) hasValue() bool mutation OptionalHasValue { evaluate( expressions: { present: "optional.of('hello').hasValue()" # true absent: "optional.none().hasValue()" # false } ) } ``` ### (optional) value Extracts the value from the optional. **Important:** This will cause an error if the optional is empty. Use `hasValue` to check first, or use `orValue`. ```graphql # func (optional_type(V)) value() V mutation OptionalValue { evaluate(expressions: { result: "optional.of('hello').value()" }) # Example: "hello" (Errors if optional is empty) } ``` ### (optional) or Takes two optionals. Returns the first optional if it has a value, otherwise returns the second optional. ```graphql # func (optional_type(V)) or(optional_type(V)) optional_type(V) mutation OptionalOr { evaluate( expressions: { first: "optional.of(1).or(optional.of(2)).value()" # 1 second: "optional.none().or(optional.of(2)).value()" # 2 bothNone: "optional.none().or(optional.none()).hasValue()" # false } ) } ``` ### (optional) orValue Extracts the value from the optional if it's present. If the optional is empty, returns the provided default value instead. ```graphql # func (optional_type(V)) orValue(V) V mutation OptionalOrValue { evaluate( expressions: { has: "optional.of(10).orValue(0)" # 10 none: "optional.none().orValue(0)" # 0 } ) } ``` ## String Manipulation A comprehensive set of functions for working with strings, mirroring many functions from Go's `strings` package and common string methods. ### Case Conversion #### strings.ToLower Converts the entire string to lowercase, respecting Unicode rules. ```graphql # func strings.ToLower(string) string mutation StringsToLower { evaluate(expressions: { result: "strings.ToLower('HELLO WORLD')" }) # Example: "hello world" } ``` #### strings.ToUpper Converts the entire string to uppercase, respecting Unicode rules. ```graphql # func strings.ToUpper(string) string mutation StringsToUpper { evaluate(expressions: { result: "strings.ToUpper('lowercase')" }) # Example: "LOWERCASE" } ``` #### strings.ToTitle Converts the string to title case (often equivalent to uppercase for simple ASCII). Unicode rules apply. ```graphql # func strings.ToTitle(string) string mutation StringsToTitle { evaluate(expressions: { result: "strings.ToTitle('loud noises')" }) # Example: "LOUD NOISES" (Often same as ToUpper for ASCII) } ``` #### strings.Title Converts the string to title case, where the first letter of each word is capitalized. Word boundaries are Unicode-aware. ```graphql # func strings.Title(string) string # Note: Title casing rules are language specific and can be complex. mutation StringsTitle { evaluate(expressions: { result: "strings.Title('war and peace')" }) # Example: "War And Peace" (simple case) } ``` #### (string) lowerAscii Converts only ASCII characters in the string to lowercase. Faster than `strings.ToLower` but doesn't handle non-ASCII characters. ```graphql # func (string) lowerAscii() string mutation StringLowerAscii { evaluate(expressions: { result: "'HELLO WORLD 123'.lowerAscii()" }) # Example: "hello world 123" } ``` #### (string) upperAscii Converts only ASCII characters in the string to uppercase. Faster than `strings.ToUpper` but doesn't handle non-ASCII characters. ```graphql # func (string) upperAscii() string mutation StringUpperAscii { evaluate(expressions: { result: "'hello world 123'.upperAscii()" }) # Example: "HELLO WORLD 123" } ``` ### Trimming Whitespace and Characters #### strings.TrimSpace Removes leading and trailing whitespace (as defined by Unicode) from the string. ```graphql # func strings.TrimSpace(string) string mutation StringsTrimSpace { evaluate( expressions: { result: "strings.TrimSpace(' \\t\\n Hello \\n\\t ') " } ) # Example: "Hello" } ``` #### strings.Trim Removes leading and trailing characters specified in the `cutset` string. ```graphql # func strings.Trim(string, string) string mutation StringsTrim { evaluate(expressions: { result: "strings.Trim('.,!Hello!,.', '.,!')" }) # Example: "Hello" } ``` #### strings.TrimLeft Removes leading characters specified in the `cutset` string. ```graphql # func strings.TrimLeft(string, string) string mutation StringsTrimLeft { evaluate(expressions: { result: "strings.TrimLeft('...Hello...', '.')" }) # Example: "Hello..." } ``` #### strings.TrimRight Removes trailing characters specified in the `cutset` string. ```graphql # func strings.TrimRight(string, string) string mutation StringsTrimRight { evaluate(expressions: { result: "strings.TrimRight('...Hello...', '.')" }) # Example: "...Hello" } ``` #### strings.TrimPrefix Removes the specified prefix from the beginning of the string, if present. ```graphql # func strings.TrimPrefix(string, string) string mutation StringsTrimPrefix { evaluate(expressions: { result: "strings.TrimPrefix('__main__', '__')" }) # Example: "main__" } ``` #### strings.TrimSuffix Removes the specified suffix from the end of the string, if present. ```graphql # func strings.TrimSuffix(string, string) string mutation StringsTrimSuffix { evaluate(expressions: { result: "strings.TrimSuffix('filename.txt', '.txt')" }) # Example: "filename" } ``` #### (string) trim Removes leading and trailing whitespace from the string (equivalent to `strings.TrimSpace`). ```graphql # func (string) trim() string mutation StringTrim { evaluate(expressions: { result: "' whitespace '.trim()" }) # Example: "whitespace" } ``` ### Searching and Indexing #### strings.Contains Checks if the string contains the specified substring. ```graphql # func strings.Contains(string, string) bool mutation StringsContains { evaluate(expressions: { result: "strings.Contains('banana', 'nan')" }) # Example: true } ``` #### strings.ContainsAny Checks if the string contains any character from the specified `chars` string. ```graphql # func strings.ContainsAny(string, string) bool mutation StringsContainsAny { evaluate(expressions: { result: "strings.ContainsAny('team', 'eiou')" }) # Example: true ('e' and 'a' are vowels) } ``` #### strings.HasPrefix Checks if the string starts with the specified prefix. ```graphql # func strings.HasPrefix(string, string) bool mutation StringsHasPrefix { evaluate(expressions: { result: "strings.HasPrefix('__main__', '__')" }) # Example: true } ``` #### strings.HasSuffix Checks if the string ends with the specified suffix. ```graphql # func strings.HasSuffix(string, string) bool mutation StringsHasSuffix { evaluate(expressions: { result: "strings.HasSuffix('image.jpg', '.jpg')" }) # Example: true } ``` #### strings.Index Finds the index of the first occurrence of the substring within the string. Returns -1 if not found. ```graphql # func strings.Index(string, string) int mutation StringsIndex { evaluate(expressions: { result: "strings.Index('banana', 'na')" }) # Example: 2 } ``` #### strings.IndexAny Finds the index of the first occurrence of any character from the `chars` string. Returns -1 if no character is found. ```graphql # func strings.IndexAny(string, string) int mutation StringsIndexAny { evaluate(expressions: { result: "strings.IndexAny('chicken', 'aeiou')" }) # Example: 2 (index of 'i') } ``` #### strings.LastIndex Finds the index of the last occurrence of the substring within the string. Returns -1 if not found. ```graphql # func strings.LastIndex(string, string) int mutation StringsLastIndex { evaluate(expressions: { result: "strings.LastIndex('banana', 'na')" }) # Example: 4 } ``` #### strings.LastIndexAny Finds the index of the last occurrence of any character from the `chars` string. Returns -1 if no character is found. ```graphql # func strings.LastIndexAny(string, string) int mutation StringsLastIndexAny { evaluate(expressions: { result: "strings.LastIndexAny('banana', 'ab')" }) # Example: 5 ('a' at index 5) } ``` #### (string) contains Checks if the string contains the specified substring (method form). ```graphql # func (string) contains(string) bool mutation StringContains { evaluate(expressions: { result: "'banana'.contains('nan')" }) # Example: true } ``` #### (string) startsWith Checks if the string starts with the specified prefix (method form). ```graphql # func (string) startsWith(string) bool mutation StringStartsWith { evaluate(expressions: { result: "'filename.txt'.startsWith('file')" }) # Example: true } ``` #### (string) endsWith Checks if the string ends with the specified suffix (method form). ```graphql # func (string) endsWith(string) bool mutation StringEndsWith { evaluate(expressions: { result: "'image.png'.endsWith('.png')" }) # Example: true } ``` #### (string) indexOf Finds the index of the first occurrence of the substring, optionally starting the search from a given index (method form). ```graphql # func (string) indexOf(string) int mutation StringIndexOfSimple { evaluate(expressions: { result: "'banana'.indexOf('na')" }) # Example: 2 } # func (string) indexOf(string, int) int mutation StringIndexOfWithStart { evaluate(expressions: { result: "'banana'.indexOf('na', 3)" }) # Example: 4 (start search from index 3) } ``` #### (string) lastIndexOf Finds the index of the last occurrence of the substring, optionally searching backwards from a given index (method form). ```graphql # func (string) lastIndexOf(string) int mutation StringLastIndexOfSimple { evaluate(expressions: { result: "'banana'.lastIndexOf('a')" }) # Example: 5 } # func (string) lastIndexOf(string, int) int mutation StringLastIndexOfWithStart { evaluate(expressions: { result: "'banana'.lastIndexOf('a', 4)" }) # Example: 3 (search backwards from index 4) } ``` ### Replacing Substrings #### strings.Replace Replaces the first `n` occurrences of `old` with `new`. If `n` is negative, all occurrences are replaced. ```graphql # func strings.Replace(string, string, string, int) string mutation StringsReplace { evaluate(expressions: { result: "strings.Replace('banana', 'a', 'o', 2)" }) # Example: "bonona" (replace first 2 'a's) } ``` #### strings.ReplaceAll Replaces all occurrences of `old` with `new`. ```graphql # func strings.ReplaceAll(string, string, string) string mutation StringsReplaceAll { evaluate(expressions: { result: "strings.ReplaceAll('banana', 'a', 'o')" }) # Example: "bonono" } ``` #### (string) replace Replaces occurrences of `old` with `new`. If `n` is provided and non-negative, replaces the first `n` occurrences. If `n` is omitted or negative, replaces all occurrences (method form). ```graphql # func (string) replace(string, string) string mutation StringReplaceSimple { evaluate(expressions: { result: "'banana'.replace('a', 'o')" }) # Example: "bonono" (replaces all) } # func (string) replace(string, string, int) string mutation StringReplaceN { evaluate(expressions: { result: "'banana'.replace('a', 'o', 2)" }) # Example: "bonona" (replaces first 2) } ``` ### Splitting and Joining #### strings.Split Splits the string into a list of strings using the separator `sep`. ```graphql # func (string) split(string) list(string) mutation StringSplit { evaluate(expressions: { result: "'a-b-c'.split('-')" }) # Example: ["a", "b", "c"] } ``` #### strings.SplitN Splits the string by `sep` into at most `n` substrings. If `n` > 0, the last substring will contain the unsplit remainder. ```graphql # func (string) split(string, int) list(string) mutation StringSplitN { evaluate(expressions: { result: "'a-b-c'.split('-', 2)" }) # Example: ["a", "b-c"] (split into n substrings) } ``` #### (list) join Concatenates a list of strings into a single string, optionally using a separator. Default separator is empty string. ```graphql # func (list(string)) join() string mutation ListStringJoinDefault { evaluate(expressions: { result: "['a', 'b', 'c'].join()" }) # Example: "abc" } # func (list(string)) join(string) string mutation ListStringJoinSeparator { evaluate(expressions: { result: "['a', 'b', 'c'].join('-')" }) # Example: "a-b-c" } ``` ### Substrings and Characters #### (string) substring Extracts a portion of the string. With one argument `start`, takes characters from `start` to the end. With `start` and `end`, takes characters from `start` up to (but not including) `end`. ```graphql # func (string) substring(int) string mutation StringSubstringFrom { evaluate(expressions: { result: "'abcdef'.substring(2)" }) # Example: "cdef" } # func (string) substring(int, int) string mutation StringSubstringRange { evaluate(expressions: { result: "'abcdef'.substring(1, 4)" }) # Example: "bcd" (exclusive end index) } ``` #### (string) charAt Returns the character (as a string) at the specified zero-based index. ```graphql # func (string) charAt(int) string mutation StringCharAt { evaluate(expressions: { result: "'hello'.charAt(1)" }) # Example: "e" } ``` #### (string) take Returns the first `n` characters of the string. ```graphql # func (string) take(int) string mutation StringTake { evaluate(expressions: { result: "'abcdef'.take(3)" }) # Example: "abc" (first n chars) } ``` #### (string) drop Returns the string with the first `n` characters removed (equivalent to `substring(n)`). ```graphql # func (string) drop(int) string mutation StringDrop { evaluate(expressions: { result: "'abcdef'.drop(2)" }) # Example: "cdef" (same as substring(n)) } ``` ### Other String Functions #### strings.Count Counts the non-overlapping occurrences of a substring within the string. ```graphql # func strings.Count(string, string) int mutation StringsCount { evaluate(expressions: { result: "strings.Count('banana', 'a')" }) # Example: 3 } ``` #### strings.EqualFold Compares two strings using case-insensitive comparison (Unicode-aware). ```graphql # func strings.EqualFold(string, string) bool mutation StringsEqualFold { evaluate(expressions: { result: "strings.EqualFold('GoLang', 'golang')" }) # Example: true } ``` #### strings.Compare Compares two strings lexicographically. Returns -1 if s1 < s2, 0 if s1 == s2, 1 if s1 > s2. ```graphql # func strings.Compare(string, string) int mutation StringsCompare { evaluate( expressions: { less: "strings.Compare('a', 'b')" # -1 equal: "strings.Compare('a', 'a')" # 0 greater: "strings.Compare('b', 'a')" # 1 } ) } ``` #### strings.Repeat Repeats the string `count` times. ```graphql # func strings.Repeat(string, int) string mutation StringsRepeat { evaluate(expressions: { result: "strings.Repeat('=', 5)" }) # Example: "=====" } ``` #### strings.ToValidUTF8 Replaces invalid UTF-8 byte sequences in the string with the specified replacement string. ```graphql # func strings.ToValidUTF8(string, string) string mutation StringsToValidUTF8 { evaluate(expressions: { result: "strings.ToValidUTF8('abc\\xffdef', '?')" }) # Example: "abc?def" } ``` #### (string) format Formats the string using placeholders (like `%s`, `%d`) and a list of dynamic arguments. Placeholder syntax depends on implementation (often similar to `sprintf`). ```graphql # func (string) format(list(dyn)) string # Note: format specifiers like %s, %d are implementation specific. Using a generic example. mutation StringFormat { evaluate( expressions: { result: "'Hello, %s! You are %d.'.format(['World', dyn(30)])" } ) # Example: "Hello, World! You are 30." (Assuming %s, %d) } ``` #### (string) reverse Reverses the order of characters in the string. ```graphql # func (string) reverse() string mutation StringReverse { evaluate(expressions: { result: "'hello'.reverse()" }) # Example: "olleh" } ``` #### (string) quote Returns a double-quoted Go string literal representing the input string, with backslash escapes for control characters and quotes. ```graphql # func strings.quote(string) string mutation StringsQuote { evaluate(expressions: { result: "strings.quote('Hello \"World\"')" }) # Example: "\"Hello \\\"World\\\"\"" } ``` #### (string) size / size(string) Returns the number of characters (runes) in the string. ```graphql # func size(string) int / func (string) size() int mutation SizeString { evaluate(expressions: { result: "size('hello')" }) # Example: 5 } ``` ## Date & Time Functions for working with timestamps, durations, and dates. ### Timestamp Manipulation #### time.Now Returns the current timestamp. ```graphql # func time.Now() google.protobuf.Timestamp mutation TimeNow { evaluate(expressions: { result: "string(time.Now())" }) # Example: Current timestamp string like "2023-10-27T10:30:00Z" (will vary) } ``` #### (timestamp) getHours Extracts the hour (0-23) from the timestamp, optionally in a specified timezone. Default is UTC. ```graphql # func (google.protobuf.Timestamp) getHours() int mutation TimestampGetHoursUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getHours()" } ) # Example: 15 } # func (google.protobuf.Timestamp) getHours(string) int mutation TimestampGetHoursTimezone { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getHours('America/New_York')" } ) # Example: 11 } ``` #### (timestamp) getMinutes Extracts the minute (0-59) from the timestamp, optionally in a specified timezone. ```graphql # func (google.protobuf.Timestamp) getMinutes() int mutation TimestampGetMinutesUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getMinutes()" } ) # Example: 4 } # func (google.protobuf.Timestamp) getMinutes(string) int mutation TimestampGetMinutesTimezone { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getMinutes('America/New_York')" } ) # Example: 4 } ``` #### (timestamp) getSeconds Extracts the second (0-59) from the timestamp, optionally in a specified timezone (though seconds are usually timezone-independent). ```graphql # func (google.protobuf.Timestamp) getSeconds() int mutation TimestampGetSecondsUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05.123Z').getSeconds()" } ) # Example: 5 } # func (google.protobuf.Timestamp) getSeconds(string) int mutation TimestampGetSecondsTimezone { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05.123Z').getSeconds('America/New_York')" } ) # Example: 5 (seconds are usually timezone independent) } ``` #### (timestamp) getMilliseconds Extracts the millisecond (0-999) part of the timestamp. ```graphql # func (google.protobuf.Timestamp) getMilliseconds() int mutation TimestampGetMillisecondsUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05.123Z').getMilliseconds()" } ) # Example: 123 } # func (google.protobuf.Timestamp) getMilliseconds(string) int mutation TimestampGetMillisecondsTimezone { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05.123Z').getMilliseconds('America/New_York')" } ) # Example: 123 (milliseconds are timezone independent) } ``` #### (timestamp) getDayOfMonth / getDate Extracts the day of the month (1-31) from the timestamp, optionally in a specified timezone. `getDate` is an alias. ```graphql # func (google.protobuf.Timestamp) getDayOfMonth() int # func (google.protobuf.Timestamp) getDate() int (alias) mutation TimestampGetDayOfMonthUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getDayOfMonth()" } ) # Example: 27 } # func (google.protobuf.Timestamp) getDayOfMonth(string) int # func (google.protobuf.Timestamp) getDate(string) int (alias) mutation TimestampGetDayOfMonthTimezone { evaluate( expressions: { result: "timestamp('2023-11-01T02:00:00Z').getDayOfMonth('America/Los_Angeles')" } ) # Example: 31 (Oct 31st in PST) } ``` #### (timestamp) getDayOfWeek Extracts the day of the week (Sunday=0, Monday=1, ..., Saturday=6) from the timestamp, optionally in a specified timezone. ```graphql # func (google.protobuf.Timestamp) getDayOfWeek() int mutation TimestampGetDayOfWeekUTC { evaluate( expressions: { result: "timestamp('2023-10-27T00:00:00Z').getDayOfWeek()" } ) # Example: 5 (Friday) } # func (google.protobuf.Timestamp) getDayOfWeek(string) int mutation TimestampGetDayOfWeekTimezone { evaluate( expressions: { result: "timestamp('2023-10-27T00:00:00Z').getDayOfWeek('America/Los_Angeles')" } ) # Example: 4 (Thursday in PST) } ``` #### (timestamp) getDayOfYear Extracts the day of the year (1-366) from the timestamp, optionally in a specified timezone. ```graphql # func (google.protobuf.Timestamp) getDayOfYear() int mutation TimestampGetDayOfYearUTC { evaluate( expressions: { result: "timestamp('2023-10-27T00:00:00Z').getDayOfYear()" } ) # Example: 300 } # func (google.protobuf.Timestamp) getDayOfYear(string) int mutation TimestampGetDayOfYearTimezone { evaluate( expressions: { result: "timestamp('2023-01-01T02:00:00Z').getDayOfYear('America/Los_Angeles')" } ) # Example: 365 (Dec 31st of previous year in PST) } ``` #### (timestamp) getMonth Extracts the month (January=0, February=1, ..., December=11) from the timestamp, optionally in a specified timezone. **Note:** This is 0-indexed, unlike `date.getMonth()`. ```graphql # func (google.protobuf.Timestamp) getMonth() int mutation TimestampGetMonthUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getMonth()" } ) # Example: 9 (October) } # func (google.protobuf.Timestamp) getMonth(string) int mutation TimestampGetMonthTimezone { evaluate( expressions: { result: "timestamp('2023-01-01T02:00:00Z').getMonth('America/Los_Angeles')" } ) # Example: 11 (December in PST) } ``` #### (timestamp) getFullYear Extracts the full year (e.g., 2023) from the timestamp, optionally in a specified timezone. ```graphql # func (google.protobuf.Timestamp) getFullYear() int mutation TimestampGetFullYearUTC { evaluate( expressions: { result: "timestamp('2023-10-27T15:04:05Z').getFullYear()" } ) # Example: 2023 } # func (google.protobuf.Timestamp) getFullYear(string) int mutation TimestampGetFullYearTimezone { evaluate( expressions: { result: "timestamp('2023-01-01T02:00:00Z').getFullYear('America/Los_Angeles')" } ) # Example: 2022 (Dec 31st of previous year in PST) } ``` ### Duration Manipulation #### (duration) getHours Calculates the total number of full hours represented by the duration. ```graphql # func (google.protobuf.Duration) getHours() int mutation DurationGetHours { evaluate(expressions: { result: "duration('3h15m').getHours()" }) # Example: 3 } ``` #### (duration) getMinutes Calculates the total number of full minutes represented by the duration. ```graphql # func (google.protobuf.Duration) getMinutes() int mutation DurationGetMinutes { evaluate(expressions: { result: "duration('1h30m').getMinutes()" }) # Example: 90 } ``` #### (duration) getSeconds Calculates the total number of seconds represented by the duration (including fractional parts if the underlying duration has them, but returns an int). ```graphql # func (google.protobuf.Duration) getSeconds() int mutation DurationGetSeconds { evaluate(expressions: { result: "duration('3m45s').getSeconds()" }) # Example: 225 } ``` #### (duration) getMilliseconds Calculates the total number of milliseconds represented by the duration. ```graphql # func (google.protobuf.Duration) getMilliseconds() int mutation DurationGetMilliseconds { evaluate(expressions: { result: "duration('1s500ms').getMilliseconds()" }) # Example: 1500 } ``` ### Date Manipulation #### date.Today Returns the current date, optionally in a specified timezone. ```graphql # func date.Today() twisp.type.v1.Date mutation DateTodayUTC { evaluate(expressions: { result: "string(date.Today())" }) # Example: Current date string in UTC e.g., "2023-10-27" (will vary) } # func date.Today(string) twisp.type.v1.Date mutation DateTodayTimezone { evaluate(expressions: { result: "string(date.Today('America/New_York'))" }) # Example: Current date string in NY e.g., "2023-10-27" (will vary) } ``` #### (date) getDay Extracts the day of the month (1-31) from the date. ```graphql # func (twisp.type.v1.Date) getDay() int mutation DateGetDay { evaluate(expressions: { result: "date('2023-10-27').getDay()" }) # Example: 27 } ``` #### (date) getMonth Extracts the month (January=1, February=2, ..., December=12) from the date. **Note:** This is 1-indexed, unlike `timestamp.getMonth()`. ```graphql # func (twisp.type.v1.Date) getMonth() int mutation DateGetMonth { evaluate(expressions: { result: "date('2023-10-27').getMonth()" }) # Example: 10 (October) } ``` #### (date) getYear Extracts the full year (e.g., 2023) from the date. ```graphql # func (twisp.type.v1.Date) getYear() int mutation DateGetYear { evaluate(expressions: { result: "date('2023-10-27').getYear()" }) # Example: 2023 } ``` #### (date) toString Converts the Date object to its string representation (YYYY-MM-DD). ```graphql # func (twisp.type.v1.Date) toString() string mutation DateToString { evaluate(expressions: { result: "date('2023-10-27').toString()" }) # Example: "2023-10-27" } ``` ### Calendar Functions (cal) #### cal.WeekOfYear Calculates calendar-specific week information (likely week number, year). The exact map structure and behavior depends on the `int` parameters (e.g., first day of week, minimum days in first week). ```graphql # func cal.WeekOfYear(google.protobuf.Timestamp, int, int) map(, ) # Note: The markdown signature for map is incomplete. Assuming map[string]int or similar based on common patterns. # This function's exact map structure isn't defined, providing a basic call. mutation CalWeekOfYear { evaluate( expressions: { result: "cal.WeekOfYear(timestamp('2023-01-01T00:00:00Z'), 1, 1)" } ) # Result depends on implementation details (e.g., {'year': 2023, 'week': 1}) } ``` #### cal.ISOWeekOfYear Calculates the ISO 8601 week date (year and week number). The exact map structure returned depends on implementation. ```graphql # func cal.ISOWeekOfYear(google.protobuf.Timestamp) map(, ) # Map structure unclear from signature. Basic call. mutation CalISOWeekOfYear { evaluate( expressions: { result: "cal.ISOWeekOfYear(timestamp('2023-01-01T00:00:00Z'))" } ) # Result depends on implementation (e.g., {'year': 2022, 'week': 52}) } ``` #### cal.Quarter Calculates the quarter (1-4) of the year for the given timestamp. The mode `int` might define quarter boundaries (e.g., fiscal vs calendar). ```graphql # func cal.Quarter(google.protobuf.Timestamp, int) int # Mode int might define quarter boundaries. Using 1 as default (calendar). mutation CalQuarter { evaluate( expressions: { result: "cal.Quarter(timestamp('2023-07-01T00:00:00Z'), 1)" } ) # Example: 3 } ``` ## Decimal Arithmetic Functions for performing calculations with high-precision decimal numbers. These are crucial for financial calculations where floating-point inaccuracies are unacceptable. ### Basic Arithmetic #### decimal.Add Adds two decimal numbers. ```graphql # func decimal.Add(twisp.type.v1.Decimal, twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalAdd { evaluate( expressions: { result: "string(decimal.Add(decimal('1.1'), decimal('2.2')))" } ) # Example: "3.3" } ``` #### decimal.Sub Subtracts the second decimal from the first. ```graphql # func decimal.Sub(twisp.type.v1.Decimal, twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalSub { evaluate( expressions: { result: "string(decimal.Sub(decimal('1.23'), decimal('0.23')))" } ) # Example: "1" } ``` #### decimal.Mul Multiplies two decimal numbers. ```graphql # func decimal.Mul(twisp.type.v1.Decimal, twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalMul { evaluate( expressions: { result: "string(decimal.Mul(decimal('1.5'), decimal('2')))" } ) # Example: "3" or "3.0" } ``` #### decimal.Quo Divides the first decimal by the second, up to a specified precision (`uint`). The exact division rules (rounding) depend on implementation context. ```graphql # func decimal.Quo(twisp.type.v1.Decimal, twisp.type.v1.Decimal, uint) twisp.type.v1.Decimal mutation DecimalQuo { evaluate( expressions: { result: "string(decimal.Quo(decimal('10'), decimal('3'), 4u))" } ) # Example: "3.3333" (precision 4) } ``` #### decimal.QuoInteger Performs integer division (truncates the result) between two decimals. The `uint` likely relates to precision context but might not directly affect the truncated result. ```graphql # func decimal.QuoInteger(twisp.type.v1.Decimal, twisp.type.v1.Decimal, uint) twisp.type.v1.Decimal mutation DecimalQuoInteger { evaluate( expressions: { result: "string(decimal.QuoInteger(decimal('10'), decimal('3'), 8u))" } ) # Example: "3" } ``` #### decimal.Rem Calculates the remainder of the division between two decimals. The `uint` might specify rounding mode for the remainder calculation. ```graphql # func decimal.Rem(twisp.type.v1.Decimal, twisp.type.v1.Decimal, uint) twisp.type.v1.Decimal # Mode uint might specify rounding for remainder. Using 0 as default. mutation DecimalRem { evaluate( expressions: { result: "string(decimal.Rem(decimal('10.5'), decimal('3'), 0u))" } ) # Example: "1.5" } ``` ### Exponents, Roots, and Logs #### decimal.Pow Raises the first decimal to the power of the second decimal. ```graphql # func decimal.Pow(twisp.type.v1.Decimal, twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalPow { evaluate( expressions: { result: "string(decimal.Pow(decimal('2'), decimal('3')))" } ) # Example: "8" } ``` #### decimal.Exp Raises the decimal to the power of an unsigned integer exponent. ```graphql # func decimal.Exp(twisp.type.v1.Decimal, uint) twisp.type.v1.Decimal mutation DecimalExp { evaluate(expressions: { result: "string(decimal.Exp(decimal('1.23'), 2u))" }) # Example: "1.5129" (1.23^2) } ``` #### decimal.Sqrt Calculates the square root of the decimal. ```graphql # func decimal.Sqrt(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalSqrt { evaluate(expressions: { result: "string(decimal.Sqrt(decimal('9')))" }) # Example: "3" } ``` #### decimal.Cbrt Calculates the cube root of the decimal. ```graphql # func decimal.Cbrt(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalCbrt { evaluate(expressions: { result: "string(decimal.Cbrt(decimal('27')))" }) # Example: "3" } ``` #### decimal.Ln Calculates the natural logarithm (base e) of the decimal. ```graphql # func decimal.Ln(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalLn { evaluate(expressions: { result: "string(decimal.Ln(decimal('10')))" }) # Example: Natural log of 10 (approx "2.302585...") } ``` #### decimal.Log10 Calculates the base-10 logarithm of the decimal. ```graphql # func decimal.Log10(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalLog10 { evaluate(expressions: { result: "string(decimal.Log10(decimal('100')))" }) # Example: "2" } ``` ### Rounding and Precision #### decimal.Round Rounds the decimal to a specified number of places (`int`) using a named rounding mode (`string`, e.g., "half_up", "half_even"). ```graphql # func decimal.Round(twisp.type.v1.Decimal, string, int) twisp.type.v1.Decimal # Rounding modes might include "half_up", "half_even", etc. mutation DecimalRound { evaluate( expressions: { result: "string(decimal.Round(decimal('1.2345'), 'half_up', 2))" } ) # Example: "1.23" } ``` #### decimal.Quantize Rounds the decimal to have the same exponent (scale) as a specified number of places (`int`). Requires a rounding mode (`uint`, check implementation for specific mode values, e.g., 4=HALF_UP). This effectively sets the number of decimal places. ```graphql # func decimal.Quantize(twisp.type.v1.Decimal, int, uint) twisp.type.v1.Decimal # e.g. exponent -2 precision of 3. mutation DecimalQuantize { evaluate( expressions: { result: "string(decimal.Quantize(decimal('1.236'), -2, 3u))" } ) # Example: "1.24" } ``` #### decimal.Ceil Rounds the decimal up to the nearest integer. ```graphql # func decimal.Ceil(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalCeil { evaluate(expressions: { result: "string(decimal.Ceil(decimal('1.23')))" }) # Example: "2" } ``` #### decimal.Reduce Removes trailing zeros from the fractional part of the decimal without changing its value. ```graphql # func decimal.Reduce(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalReduce { evaluate(expressions: { result: "string(decimal.Reduce(decimal('1.2300')))" }) # Example: "1.23" } ``` ### Comparison and Sign #### decimal.Cmp Compares two decimals. Returns a decimal value: -1 if d1 < d2, 0 if d1 == d2, 1 if d1 > d2. ```graphql # func decimal.Cmp(twisp.type.v1.Decimal, twisp.type.v1.Decimal) twisp.type.v1.Decimal # Returns -1, 0, or 1 as Decimal mutation DecimalCmp { evaluate( expressions: { less: "string(decimal.Cmp(decimal('1'), decimal('2')))" # "-1" equal: "string(decimal.Cmp(decimal('2'), decimal('2')))" # "0" greater: "string(decimal.Cmp(decimal('3'), decimal('2')))" # "1" } ) } ``` #### decimal.Abs Returns the absolute value of the decimal. ```graphql # func decimal.Abs(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalAbs { evaluate(expressions: { result: "string(decimal.Abs(decimal('-1.23')))" }) # Example: "1.23" } ``` #### decimal.Neg Returns the negation of the decimal. ```graphql # func decimal.Neg(twisp.type.v1.Decimal) twisp.type.v1.Decimal mutation DecimalNeg { evaluate(expressions: { result: "string(decimal.Neg(decimal('1.23')))" }) # Example: "-1.23" } ``` ### Conversion #### (decimal) toString Converts the Decimal object to its string representation. ```graphql # func (twisp.type.v1.Decimal) toString() string mutation DecimalToString { evaluate(expressions: { result: "decimal('123.456').toString()" }) # Example: "123.456" } ``` ## Money Arithmetic Functions for performing calculations with Money objects, ensuring currency consistency. ### money.Add Adds two Money objects. Requires both operands to have the same currency. ```graphql # func money.Add(twisp.type.v1.Money, twisp.type.v1.Money) twisp.type.v1.Money mutation MoneyAdd { evaluate( expressions: { result: "money.Add(money('10', 'USD'), money('5.50', 'USD'))" } ) # Example: "15.50 USD" } ``` ### money.Sub Subtracts the second Money object from the first. Requires both operands to have the same currency. ```graphql # func money.Sub(twisp.type.v1.Money, twisp.type.v1.Money) twisp.type.v1.Money mutation MoneySub { evaluate( expressions: { result: "money.Sub(money('10.00', 'USD'), money('5.50', 'USD'))" } ) # Example: "4.50 USD" } ``` ### money.Mul Multiplies a Money object by a scalar factor (provided as a string representing a decimal). ```graphql # func money.Mul(twisp.type.v1.Money, string) twisp.type.v1.Money mutation MoneyMul { evaluate( expressions: { result: "money.Mul(money('10.50', 'USD'), '2')" } ) # Example: "21.00 USD" } ``` ### money.Div Divides a Money object by a scalar factor (provided as a string representing a decimal). ```graphql # func money.Div(twisp.type.v1.Money, string) twisp.type.v1.Money mutation MoneyDiv { evaluate( expressions: { result: "money.Div(money('21.00', 'USD'), '2')" } ) # Example: "10.50 USD" } ``` ### (money) currency Returns the currency code of the Money object as a string. ```graphql # func (twisp.type.v1.Money) currency() string mutation MoneyCurrency { evaluate(expressions: { result: "money('10.00', 'EUR').currency()" }) # Example: "EUR" } ``` ### (money) decimal Converts the Money object to its Decimal value (amount only, currency is discarded). ```graphql # func (twisp.type.v1.Money) decimal() twisp.type.v1.Decimal mutation MoneyDecimalConversion { evaluate(expressions: { fromMoneyMethod: "string(money('50.00', 'EUR').decimal())" # "50.00" }) } ``` ## Math Functions Standard mathematical functions operating primarily on `double` values. These mirror functions from Go's `math` package. ### Basic Operations #### math.Abs Returns the absolute value of a double. ```graphql # func math.Abs(double) double mutation MathAbs { evaluate(expressions: { result: "math.Abs(-5.5)" }) # Example: 5.5 } ``` #### math.Max Returns the larger of two double values. ```graphql # func math.Max(double, double) double mutation MathMax { evaluate(expressions: { result: "math.Max(5.0, 3.0)" }) # Example: 5.0 } ``` #### math.Min Returns the smaller of two double values. ```graphql # func math.Min(double, double) double mutation MathMin { evaluate(expressions: { result: "math.Min(5.0, 3.0)" }) # Example: 3.0 } ``` #### math.Dim Returns the maximum of `x-y` or `0`. (Positive difference). ```graphql # func math.Dim(double, double) double mutation MathDim { evaluate( expressions: { pos: "math.Dim(5.0, 2.0)" # 3.0 (x-y) neg: "math.Dim(2.0, 5.0)" # 0.0 (max(x-y, 0)) } ) } ``` #### math.Copysign Returns a value with the magnitude of the first argument and the sign of the second argument. ```graphql # func math.Copysign(double, double) double mutation MathCopysign { evaluate(expressions: { result: "math.Copysign(5.0, -1.0)" }) # Example: -5.0 } ``` #### math.Signbit Reports whether the number is negative or negative zero. ```graphql # func math.Signbit(double) bool mutation MathSignbit { evaluate( expressions: { neg: "math.Signbit(-5.0)" # true pos: "math.Signbit(5.0)" # false } ) } ``` ### Rounding and Truncation #### math.Ceil Returns the least integer value greater than or equal to the input. ```graphql # func math.Ceil(double) double mutation MathCeil { evaluate(expressions: { result: "math.Ceil(3.1)" }) # Example: 4.0 } ``` #### math.Floor Returns the greatest integer value less than or equal to the input. ```graphql # func math.Floor(double) double mutation MathFloor { evaluate(expressions: { result: "math.Floor(3.9)" }) # Example: 3.0 } ``` #### math.Round Returns the nearest integer, rounding half away from zero. ```graphql # func math.Round(double) double mutation MathRound { evaluate(expressions: { result: "math.Round(3.5)" }) # Example: 4.0 } ``` #### math.RoundToEven Returns the nearest integer, rounding ties to the nearest even integer (Banker's rounding). ```graphql # func math.RoundToEven(double) double mutation MathRoundToEven { evaluate( expressions: { halfUp: "math.RoundToEven(2.5)" # 2.0 (rounds to nearest even integer) halfDown: "math.RoundToEven(3.5)" # 4.0 } ) } ``` #### math.Trunc Returns the integer part of the double (truncates towards zero). ```graphql # func math.Trunc(double) double mutation MathTrunc { evaluate(expressions: { result: "math.Trunc(3.14159)" }) # Example: 3.0 } ``` ### Powers, Roots, and Logs #### math.Pow Returns x**y, the base-x exponential of y. ```graphql # func math.Pow(double, double) double mutation MathPow { evaluate(expressions: { result: "math.Pow(2.0, 3.0)" }) # Example: 8.0 } ``` #### math.Pow10 Returns 10**n, the base-10 exponential of n (n is int). ```graphql # func math.Pow10(int) double mutation MathPow10 { evaluate(expressions: { result: "math.Pow10(3)" }) # Example: 1000.0 } ``` #### math.Sqrt Returns the square root of x. ```graphql # func math.Sqrt(double) double mutation MathSqrt { evaluate(expressions: { result: "math.Sqrt(9.0)" }) # Example: 3.0 } ``` #### math.Cbrt Returns the cube root of x. ```graphql # func math.Cbrt(double) double mutation MathCbrt { evaluate(expressions: { result: "math.Cbrt(27.0)" }) # Example: 3.0 } ``` #### math.Log Returns the natural logarithm (base e) of x. ```graphql # func math.Log(double) double mutation MathLog { evaluate(expressions: { result: "math.Log(10.0)" }) # Example: ~2.302585 (natural log) } ``` #### math.Log10 Returns the base-10 logarithm of x. ```graphql # func math.Log10(double) double mutation MathLog10 { evaluate(expressions: { result: "math.Log10(100.0)" }) # Example: 2.0 } ``` #### math.Log2 Returns the base-2 logarithm of x. ```graphql # func math.Log2(double) double mutation MathLog2 { evaluate(expressions: { result: "math.Log2(8.0)" }) # Example: 3.0 } ``` #### math.Log1p Returns the natural logarithm of 1+x. More accurate than `Log(1+x)` for small x. ```graphql # func math.Log1p(double) double mutation MathLog1p { evaluate(expressions: { result: "math.Log1p(0.0)" }) # Example: 0.0 (ln(1+0)) } ``` #### math.Exp Returns e**x, the base-e exponential of x. ```graphql # func math.Exp(double) double mutation MathExp { evaluate(expressions: { result: "math.Exp(1.0)" }) # Example: ~2.71828 (e^1) } ``` #### math.Exp2 Returns 2**x, the base-2 exponential of x. ```graphql # func math.Exp2(double) double mutation MathExp2 { evaluate(expressions: { result: "math.Exp2(3.0)" }) # Example: 8.0 (2^3) } ``` #### math.Expm1 Returns e**x - 1. More accurate than `Exp(x) - 1` for small x. ```graphql # func math.Expm1(double) double mutation MathExpm1 { evaluate(expressions: { result: "math.Expm1(0.0)" }) # Example: 0.0 (exp(0)-1) } ``` ### Trigonometry and Geometry #### math.Hypot Returns Sqrt(p*p + q*q), the length of the hypotenuse of a right triangle with legs p and q. ```graphql # func math.Hypot(double, double) double mutation MathHypot { evaluate(expressions: { result: "math.Hypot(3.0, 4.0)" }) # Example: 5.0 } ``` ### Other Math Functions #### math.Mod Returns the floating-point remainder of x/y. The result has the same sign as x. ```graphql # func math.Mod(double, double) double mutation MathMod { evaluate(expressions: { result: "math.Mod(10.0, 3.0)" }) # Example: 1.0 } ``` #### math.Remainder Returns the IEEE 754 floating-point remainder of x/y. ```graphql # func math.Remainder(double, double) double mutation MathRemainder { evaluate(expressions: { result: "math.Remainder(10.5, 3.0)" }) # Example: 1.5 } ``` #### math.FMA Returns x * y + z, computed with only one rounding. (Fused Multiply-Add). ```graphql # func math.FMA(double, double, double) double mutation MathFMA { evaluate(expressions: { result: "math.FMA(2.0, 3.0, 4.0)" }) # Example: 10.0 (2*3 + 4) } ``` ## Random Number Generation (rand) Functions for generating pseudo-random numbers, based on Go's `math/rand`. ### Integers #### rand.Int Returns a non-negative pseudo-random 64-bit integer. ```graphql # func rand.Int() int mutation RandInt { evaluate(expressions: { result: "rand.Int()" }) # Example: A random int64 value (e.g., 1234567890123456789) } ``` #### rand.Int31 Returns a non-negative pseudo-random 31-bit integer as an int. ```graphql # func rand.Int31() int mutation RandInt31 { evaluate(expressions: { result: "rand.Int31()" }) # Example: Random non-negative int32 (e.g., 1073741823) } ``` #### rand.Int63 Returns a non-negative pseudo-random 63-bit integer as an int. ```graphql # func rand.Int63() int mutation RandInt63 { evaluate(expressions: { result: "rand.Int63()" }) # Example: Random non-negative int64 (e.g., 4611686018427387903) } ``` #### rand.Intn Returns a non-negative pseudo-random integer in the range [0, n). Panics if n <= 0. ```graphql # func rand.Intn(int) int mutation RandIntn { evaluate(expressions: { result: "rand.Intn(100)" }) # Example: Random int between 0 and 99 } ``` #### rand.Int31n Returns a non-negative pseudo-random 31-bit integer in the range [0, n). Panics if n <= 0. ```graphql # func rand.Int31n(int) int mutation RandInt31n { evaluate(expressions: { result: "rand.Int31n(1000)" }) # Random int32 between 0 and 999 } ``` #### rand.Int63n Returns a non-negative pseudo-random 63-bit integer in the range [0, n). Panics if n <= 0. ```graphql # func rand.Int63n(int) int mutation RandInt63n { evaluate(expressions: { result: "rand.Int63n(100)" }) # Example: A random int64 between 0 and 99 } ``` ### Unsigned Integers #### rand.Uint32 Returns a pseudo-random 32-bit value as a uint. ```graphql # func rand.Uint32() uint mutation RandUint32 { evaluate(expressions: { result: "rand.Uint32()" }) # Example: Random uint32 (e.g., 2147483647u) } ``` #### rand.Uint64 Returns a pseudo-random 64-bit value as a uint. ```graphql # func rand.Uint64() uint mutation RandUint64 { evaluate(expressions: { result: "rand.Uint64()" }) # Example: A random uint64 value (e.g., 9223372036854775807u) } ``` ### Floating-Point Numbers #### rand.Float32 Returns a pseudo-random float32 in [0.0, 1.0). Returned as a double. ```graphql # func rand.Float32() double mutation RandFloat32 { evaluate(expressions: { result: "rand.Float32()" }) # Example: Random float32 (returned as double) between 0.0 and 1.0 (e.g., 0.1234567) } ``` #### rand.Float64 Returns a pseudo-random float64 in [0.0, 1.0). ```graphql # func rand.Float64() double mutation RandFloat64 { evaluate(expressions: { result: "rand.Float64()" }) # Example: Random float64 between 0.0 and 1.0 (e.g., 0.987654321) } ``` #### rand.NormFloat64 Returns a normally distributed float64 value with mean 0 and standard deviation 1. ```graphql # func rand.NormFloat64() double mutation RandNormFloat64 { evaluate(expressions: { result: "rand.NormFloat64()" }) # Example: Random normally distributed float64 (e.g., -0.54321) } ``` #### rand.ExpFloat64 Returns an exponentially distributed float64 value with rate parameter 1. ```graphql # func rand.ExpFloat64() double mutation RandExpFloat64 { evaluate(expressions: { result: "rand.ExpFloat64()" }) # Example: Random exponentially distributed float64 (e.g., 1.2345) } ``` ## Hashing & Checksums Functions for calculating various hash digests. These typically operate on `bytes`. ### MD5 Calculates the MD5 hash (128-bit). **Note:** MD5 is cryptographically broken and should not be used for security purposes. ```graphql # func md5.Sum(bytes) bytes mutation Md5Sum { evaluate(expressions: { result: "hex.EncodeToString(md5.Sum(b'hello'))" }) # Example: "5d41402abc4b2a76b9719d911017c592" } ``` ### SHA-1 Calculates the SHA-1 hash (160-bit). **Note:** SHA-1 is also considered cryptographically weak and should be avoided for security contexts. ```graphql # func sha1.Sum(bytes) bytes mutation Sha1Sum { evaluate(expressions: { result: "hex.EncodeToString(sha1.Sum(b'hello'))" }) # Example: "aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d" } ``` ### SHA-256 Calculates the SHA-256 hash (256-bit). A standard secure hashing algorithm. ```graphql # func sha256.Sum256(bytes) bytes mutation Sha256Sum256 { evaluate( expressions: { result: "hex.EncodeToString(sha256.Sum256(b'hello'))" } ) # Example: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" } ``` ### SHA-512 Calculates the SHA-512 hash (512-bit). A standard secure hashing algorithm. ```graphql # func sha512.Sum512(bytes) bytes mutation Sha512Sum512 { evaluate( expressions: { result: "hex.EncodeToString(sha512.Sum512(b'hello'))" } ) # Example: "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043" } ``` ### System Hashes #### system.hash.xx Calculates a non-cryptographic xxHash64 hash, returning a `uint`. Useful for fast hashing where collision resistance is less critical than speed. ```graphql # func system.hash.xx(bytes) uint mutation SystemHashXx { evaluate(expressions: { result: "system.hash.xx(b'data')" }) # Example: xxHash64 uint result (e.g., 17241709254074915385u) } ``` #### system.hash.jump Implements the Jump Consistent Hash algorithm. Given a `uint` key and an `int` number of buckets, returns a bucket index (`int` from 0 to num_buckets-1) consistently assigned to that key. Useful for distributing items across shards/buckets. ```graphql # func system.hash.jump(uint, int) int mutation SystemHashJump { evaluate(expressions: { result: "system.hash.jump(123456789u, 10)" }) # Example: Jump consistent hash bucket index (0-9) (e.g., 7) } ``` ## Encoding & Decoding Functions for converting data between different representations (e.g., bytes to hex, base64). ### Hexadecimal #### hex.EncodeToString Encodes a byte sequence into its hexadecimal string representation. ```graphql # func hex.EncodeToString(bytes) string mutation HexEncodeToString { evaluate( expressions: { result: "hex.EncodeToString(b'\\xDE\\xAD\\xBE\\xEF')" } ) # Example: "deadbeef" } ``` #### hex.DecodeString Decodes a hexadecimal string representation back into a byte sequence. ```graphql # func hex.DecodeString(string) bytes mutation HexDecodeString { evaluate(expressions: { result: "string(hex.DecodeString('68656c6c6f'))" }) # Example: "hello" (bytes converted back to string for display) } ``` ### Base64 #### base64.encode Encodes a byte sequence into its Base64 string representation (standard encoding). ```graphql # func base64.encode(bytes) string mutation Base64Encode { evaluate(expressions: { result: "base64.encode(b'hello world')" }) # Example: "aGVsbG8gd29ybGQ=" } ``` #### base64.decode Decodes a Base64 string representation back into a byte sequence. ```graphql # func base64.decode(string) bytes mutation Base64Decode { evaluate(expressions: { result: "string(base64.decode('aGVsbG8gd29ybGQ='))" }) # Example: "hello world" (bytes converted back to string) } ``` ### HTML Escaping #### html.EscapeString Escapes special HTML characters (`<`, `>`, `&`, `"`, `'`) into their corresponding HTML entities. Useful for preventing XSS when embedding strings in HTML. ```graphql # func html.EscapeString(string) string mutation HtmlEscapeString { evaluate( expressions: { result: "html.EscapeString('')" } ) # Example: "<script>alert("XSS")</script>" } ``` #### html.UnescapeString Unescapes HTML entities (like `<`, `&`, `"`) back into their original characters. ```graphql # func html.UnescapeString(string) string mutation HtmlUnescapeString { evaluate( expressions: { result: "html.UnescapeString('<tag> & "quote"')" } ) # Example: " & \"quote\"" } ``` ### URL Escaping #### url.PathEscape Escapes a string so it can be safely placed in a URL path segment. Spaces become `%20`, `/` remains unescaped. ```graphql # func url.PathEscape(string) string mutation UrlPathEscape { evaluate(expressions: { result: "url.PathEscape('a b/c?d=e')" }) # Example: "a%20b/c%3Fd=e" } ``` #### url.QueryEscape Escapes a string so it can be safely placed in a URL query parameter value. Spaces become `+` (or `%20` depending on context/implementation). ```graphql # func url.QueryEscape(string) string mutation UrlQueryEscape { evaluate( expressions: { result: "url.QueryEscape('key=value&another key=a/b')" } ) # Example: "key%3Dvalue%26another+key%3Da%2Fb" } ``` ### JSON Marshaling #### json.Marshal Converts a CEL value (often a map or list, represented as `dyn` or `google.protobuf.Any`) into its JSON byte representation. ```graphql # func json.Marshal(google.protobuf.Any) bytes # Requires a proto Any type, harder to demo simply. Example assumes a map can be marshaled. mutation JsonMarshal { evaluate(expressions: { result: "string(json.Marshal({'key': 'value'}))" }) # Example: "{'key': 'value'}" (or similar JSON bytes as string) } ``` ## Path Manipulation (path) Functions for working with slash-separated file paths, mirroring Go's `path` package. ### path.Base Returns the last element of the path (the filename or directory name). ```graphql # func path.Base(string) string mutation PathBase { evaluate(expressions: { result: "path.Base('/usr/local/file.txt')" }) # Example: "file.txt" } ``` ### path.Clean Returns the shortest path name equivalent to the path by purely lexical processing. It applies the following rules iteratively until no further processing can be done: 1. Replace multiple slashes with a single slash. 2. Eliminate each `.` path name element (the current directory). 3. Eliminate each inner `..` path name element (the parent directory) along with the preceding non-`..` element. 4. Eliminate `..` elements that begin a rooted path: that is, replace `/..` by `/` at the beginning of a path. ```graphql # func path.Clean(string) string mutation PathClean { evaluate(expressions: { result: "path.Clean('/a/b/../c//d')" }) # Example: "/a/c/d" } ``` ### path.Dir Returns all but the last element of the path, typically the path's directory. ```graphql # func path.Dir(string) string mutation PathDir { evaluate(expressions: { result: "path.Dir('/usr/local/bin')" }) # Example: "/usr/local" } ``` ### path.Ext Returns the file name extension used by path. The extension is the suffix beginning at the final dot in the final element of path; it is empty if there is no dot. ```graphql # func path.Ext(string) string mutation PathExt { evaluate(expressions: { result: "path.Ext('archive.tar.gz')" }) # Example: ".gz" } ``` ### path.IsAbs Reports whether the path is absolute (begins with `/`). ```graphql # func path.IsAbs(string) bool mutation PathIsAbs { evaluate( expressions: { absolute: "path.IsAbs('/home/user')" # true relative: "path.IsAbs('data/file')" # false } ) } ``` ## UUID Generation & Manipulation (uuid) Functions specifically for creating UUIDs. ### uuid.New Generates a new Version 4 (random) UUID. ```graphql # func uuid.New() twisp.type.v1.UUID mutation UuidNew { evaluate(expressions: { result: "string(uuid.New())" }) # Example: A new Version 4 UUID string (e.g., "f47ac10b-58cc-4372-a567-0e02b2c3d479") } ``` ### uuid.NewMD5 Generates a Version 3 (MD5 hash-based) UUID from a namespace UUID and a name (bytes). ```graphql # func uuid.NewMD5(twisp.type.v1.UUID, bytes) twisp.type.v1.UUID mutation UuidNewMD5 { evaluate(expressions: { result: "string(uuid.NewMD5(uuid.New(), b'data'))" }) # Example: MD5-based UUID string (e.g., "a1b...") } ``` ### uuid.NewSHA1 Generates a Version 5 (SHA-1 hash-based) UUID from a namespace UUID and a name (bytes). ```graphql # func uuid.NewSHA1(twisp.type.v1.UUID, bytes) twisp.type.v1.UUID mutation UuidNewSHA1 { evaluate(expressions: { result: "string(uuid.NewSHA1(uuid.New(), b'data'))" }) # Example: SHA1-based UUID string (e.g., "c2d...") } ``` ### (uuid) toString Converts the UUID object to its standard string representation. ```graphql # func (twisp.type.v1.UUID) toString() string mutation UuidToString { evaluate( expressions: { result: "uuid('123e4567-e89b-12d3-a456-426614174000').toString()" } ) # Example: "123e4567-e89b-12d3-a456-426614174000" } ``` ## Finance Functions (finance) Specialized functions for financial calculations. Examples provided are basic calls; understanding the financial formulas is necessary for correct usage. *Note: The exact signatures and behavior might vary.* ### finance.PrincipalPayment Calculates the principal portion of a loan payment for a given period. Arguments typically include rate per period, payment period number, total number of periods, present value (loan amount), future value, and payment type (0 for end of period, 1 for beginning). ```graphql # func finance.PrincipalPayment(double, int, int, double, double, int) double mutation FinancePrincipalPayment { evaluate( expressions: { # Example: Principal for period 1 of a $200k, 30yr (360mo) loan at 5% APR (0.05/12 monthly) result: "finance.PrincipalPayment(0.05/12.0, 1, 360, 200000.0, 0.0, 0)" } ) # Example financial calculation result (e.g., ~239.98) } ``` ### finance.InterestPayment Calculates the interest portion of a loan payment for a given period. Arguments are similar to `PrincipalPayment`. ```graphql # func finance.InterestPayment(double, int, int, double, double, int) double mutation FinanceInterestPayment { evaluate( expressions: { # Example: Interest for period 1 of a $200k, 30yr (360mo) loan at 5% APR (0.05/12 monthly) result: "finance.InterestPayment(0.05/12.0, 1, 360, 200000.0, 0.0, 0)" } ) # Example financial calculation result (e.g., ~833.33) } ``` ### finance.Payment Calculates the total payment (principal + interest) per period for a loan or annuity. Arguments include rate per period, number of periods, present value, future value, and payment type. ```graphql # func finance.Payment(double, int, double, double, int) double mutation FinancePayment { evaluate( expressions: { # Example: Total payment for a $200k, 30yr (360mo) loan at 5% APR (0.05/12 monthly) result: "finance.Payment(0.05/12.0, 360, 200000.0, 0.0, 0)" } ) # Example financial calculation result (e.g., ~1073.31) } ``` *(Other finance functions like Rate, PresentValue, FutureValue, Depreciation, etc., would follow a similar pattern with example calls based on their expected arguments)* ## System & Utility Functions Miscellaneous functions for tasks like printing, type checking, and collection manipulation. ### print Outputs the provided message and value to the system logs (side-effect) and returns the value itself. Useful for debugging CEL expressions. ```graphql # func print(string, google.protobuf.Any) google.protobuf.Any # Print is for side-effects (logging), returns its second argument. mutation PrintExample { evaluate(expressions: { result: "print('Input value:', 123)" }) # Example: 123 (and logs 'Input value: 123' server-side) } ``` ### system.mergeMap Merges two maps (represented as `dyn`). Keys from the second map overwrite keys in the first map if they overlap. ```graphql # func system.mergeMap(dyn, dyn) dyn mutation SystemMergeMap { # Merges second map into first, overwriting common keys evaluate( expressions: { result: "system.mergeMap({'a': 1, 'b': 2}, {'b': 3, 'c': 4})" } ) # Example: {'a': 1, 'b': 3, 'c': 4} } ``` ### system.unique Removes duplicate UUIDs from a list of UUIDs. The order of the remaining unique elements is not guaranteed. ```graphql # func system.unique(list(twisp.type.v1.UUID)) list(twisp.type.v1.UUID) mutation SystemUnique { evaluate( expressions: { # Constructing UUIDs inline for example ids: "[uuid('11111111-1111-1111-1111-111111111111'), uuid('22222222-2222-2222-2222-222222222222'), uuid('11111111-1111-1111-1111-111111111111')]" uniqueIds: "system.unique([uuid('11111111-1111-1111-1111-111111111111'), uuid('22222222-2222-2222-2222-222222222222'), uuid('11111111-1111-1111-1111-111111111111')])" # uniqueIds result should be the first two UUIDs (order might vary) # e.g., [uuid('11111111-1111-1111-1111-111111111111'), uuid('22222222-2222-2222-2222-222222222222')] } ) } ``` ### Size Functions Calculates the size (number of elements or characters) of various types. ```graphql # func size(bytes) int / func (bytes) size() int mutation SizeBytes { evaluate(expressions: { result: "size(b'hello')" }) # Example: 5 } # func size(list(A)) int / func (list(A)) size() int mutation SizeList { evaluate(expressions: { result: "size([1, 2, 3])" }) # Example: 3 } # func size(map(A, B)) int / func (map(A, B)) size() int mutation SizeMap { evaluate(expressions: { result: "size({'a': 1, 'b': 2})" }) # Example: 2 } # func size(string) int / func (string) size() int mutation SizeString { evaluate(expressions: { result: "size('hello')" }) # Example: 5 } ``` ### Regex Matching #### matches Performs a regular expression match using RE2 syntax. Can be used as a global function or a method on strings. ```graphql # func matches(string, string) bool # This is a global function, often used as receiver method. mutation GlobalMatches { evaluate(expressions: { result: "matches('abc', '^a.*c$')" }) # Example: true } # func (string) matches(string) bool mutation StringMatches { evaluate(expressions: { result: "'abc'.matches('^a.*c$')" }) # Example: true } ``` --- # Functions Standard functions included in the Twisp CEL runtime. CEL provides function invocation within expressions to perform operations and computations. Twisp includes a number of predefined extensions to the CEL runtime environment for computation within ledger transactions. ## Packages The included package functions are: 1. **Strongly-typed**: The function signatures of a package require that the arguments provided have the expected types. 1. **Side-effect-free**: Package functions only calculate an output based on the inputs given. The Twisp CEL runtime has been extended with the following packages and their respective function signatures. ### cal #### `func cal.Quarter(ts &{types Timestamp}, fiscalStartMonth int) int` Quarter returns the quarter based on the fiscalStartMonth: fiscalStartMonth: 1 (time.January) standard fiscalStartMonth: 10 (time.October) US Government #### `func cal.WeekOfYear(ts &{types Timestamp}, dow int, doy int) YearWeek` WeekOfYear returns the week of year given: - dow day of week that starts the week (Sunday:0 - Saturday: 6) - doy first January day that must appear in week 1. Common Settings: USA: dow 0 doy 1 (First January 1st in year) ISO: dow 1 doy 4 (First Thursday of year equivalent to first Jan 4 in year) #### `func cal.ISOWeekOfYear(ts &{types Timestamp}) YearWeek` ISOWeekOfYear returns the ISO year and week of the timestamp. See https://en.wikipedia.org/wiki/ISO_8601#Week_dates ### decimal #### `func decimal.Abs(x decimal) decimal, error` Abs calculates |x| (the absolute value of x). #### `func decimal.Add(x decimal, y decimal) decimal, error` Add calculates the sum of x+y. #### `func decimal.Cbrt(x decimal) decimal, error` Cbrt calculates the cube root of x. #### `func decimal.Ceil(x decimal) decimal, error` Ceil calculates smallest integer >= x. #### `func decimal.Cmp(x decimal, y decimal) decimal, error` Cmp compares x and y and calculates: ``` -1 if x < y 0 if x == y +1 if x > y ``` This comparison respects the normal rules of special values (like NaN), and does not compare them. #### `func decimal.Exp(x decimal, precision uint32) decimal, error` Exp calculates e**x. #### `func decimal.Ln(x decimal) decimal, error` Ln calculates the natural log of x. #### `func decimal.Log10(x decimal) decimal, error` Log10 calculates the base 10 log of x. #### `func decimal.Mul(x decimal, y decimal) decimal, error` Mul calculates the product x*y. #### `func decimal.Neg(x decimal) decimal, error` Neg calculates -x. #### `func decimal.Pow(x decimal, y decimal) decimal, error` Pow calculates x**y. #### `func decimal.Quantize(x decimal, exp int, precision uint32) decimal, error` Quantize calculates and rounds x as necessary so it is represented with exponent exp. #### `func decimal.Quo(x decimal, y decimal, precision uint32) decimal, error` Quo calculates the quotient x/y for y != 0. #### `func decimal.QuoInteger(x decimal, y decimal, precision uint32) decimal, error` QuoInteger calculates the integer part of the quotient x/y #### `func decimal.Reduce(x decimal) decimal, error` Reduce calculates x with all trailing zeros removed. #### `func decimal.Rem(x decimal, y decimal, precision uint32) decimal, error` Rem calculates the remainder part of the quotient x/y. #### `func decimal.Sqrt(x decimal) decimal, error` Sqrt calculates the square root of x. Sqrt uses the Babylonian method for computing the square root, which uses O(log p) steps for p digits of precision. #### `func decimal.Sub(x decimal, y decimal) decimal, error` Sub calculates the difference x-y. #### `func decimal.Round(x decimal, mode string, digits int) decimal, error` Round rounds x to the number of digits with the specified rounding mode. Supported rounding modes: ``` down ``` Rounds toward 0; truncate. ``` half_up ``` Rounds up if the digits are >= 0.5. ``` half_even ``` Rounds up if the digits are > 0.5. If the digits are equal to 0.5, it rounds up if the previous digit is odd, always producing an even digit. ``` ceiling ``` Rounds towards +Inf: rounds up if digits are > 0 and the number is positive. ``` floor ``` Rounds towards -Inf: rounds up if digits are > 0 and the number is negative. ``` half_down ``` Rounds up if the digits are > 0.5. ``` up ``` Rounds away from 0. ``` 05up ``` Rounds zero or five away from 0; same as round-up, except that rounding up only occurs if the digit to be rounded up is 0 or 5. #### `func decimal.Min(a decimal, b decimal) decimal` Min returns the min of a and b. If equal, returns b. #### `func decimal.Max(a decimal, b decimal) decimal` Max returns the max of a and b. If equal, returns b. ### finance #### `func finance.DaysDifference(date1 int64, date2 int64, basis int) int` DaysDifference returns the difference of days between two dates based on a daycount basis. Date1 and date2 are UNIX timestamps (seconds). "basis" must be one of: 0 = US(NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360. #### `func finance.DaysPerYear(year int, basis int) int` DaysPerYear returns the number of days in the year based on a daycount basis. "basis" must be one of: 0 = US(NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360. #### `func finance.DepreciationFixedDeclining(cost float64, salvage float64, life int, period int, month int) float64, error` DepreciationFixedDeclining returns the depreciation of an asset using the fixed-declining balance method. Excel equivalent: DB. "basis" must be one of: 0 = US(NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360. #### `func finance.DepreciationSYD(cost float64, salvage float64, life int, per int) float64` DepreciationSYD returns the depreciation for an asset in a given period using the sum-of-years' digits method. Excel equivalent: SYD. #### `func finance.DepreciationStraightLine(cost float64, salvage float64, life int) float64, error` DepreciationStraightLine returns the straight-line depreciation of an asset for each period. Excel equivalent: SLN. #### `func finance.DiscountRate(settlement int64, maturity int64, price float64, redemption float64, basis int) float64` DiscountRate returns the discount rate for a bond "settlement" is the unix timestamp (seconds) for the settlement date. "maturity" is the unix timestamp (seconds) for the maturity date. "price" is the bond's price per $100 face value. "redemption" is the bond's redemption value per $100 face value. Excel equivalent: DISC. "basis" must be one of: 0 = US(NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360. #### `func finance.EffectiveRate(nominal float64, numPeriods int) float64, error` EffectiveRate returns the effective interest rate given the nominal rate and the number of compounding payments per year. Excel equivalent: EFFECT. #### `func finance.FutureValue(rate float64, numPeriods int, pmt float64, pv float64, paymentType int)fv float64, err error` FutureValue returns the Future Value of a cash flow with constant payments and interest rate (annuities). Excel equivalent: FV. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.InterestPayment(rate float64, period int, numPeriods int, pv float64, fv float64, paymentType int) float64, error` InterestPayment returns the interest payment for a given period for a cash flow with constant periodic payments (annuities). Excel equivalent: IMPT. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.NominalRate(effectiveRate float64, numPeriods int) float64, error` NominalRate returns the nominal interest rate given the effective rate and the number of compounding payments per year. Excel equivalent: NOMINAL. #### `func finance.Payment(rate float64, numPeriods int, pv float64, fv float64, paymentType int)pmt float64, err error` Payment returns the constant payment (annuity) for a cash flow with a constant interest rate. Excel equivalent: PMT. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.Periods(rate float64, pmt float64, pv float64, fv float64, paymentType int)numPeriods float64, err error` Periods returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate. Excel equivalent: NPER. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.PresentValue(rate float64, numPeriods int, pmt float64, fv float64, paymentType int)pv float64, err error` PresentValue returns the Present Value of a cash flow with constant payments and interest rate (annuities). Excel equivalent: PV. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.PriceDiscount(settlement int64, maturity int64, discount float64, redemption float64, basis int) float64` PriceDiscount returns the price per $100 face value of a discounted bond. "settlement" is the unix timestamp (seconds) for the settlement date. "maturity" is the unix timestamp (seconds) for the maturity date. "discount" is the bond's discount rate. "redemption" is the bond's redemption value per $100 face value. Excel equivalent: PRICEDISC. "basis" must be one of: 0 = US(NASD) 30/360, 1 = Actual/actual, 2 = Actual/360, 3 = Actual/365, 4 = European 30/360. #### `func finance.PrincipalPayment(rate float64, period int, numPeriods int, pv float64, fv float64, paymentType int) float64, error` PrincipalPayment returns the principal payment for a given period for a cash flow with constant periodic payments (annuities). Excel equivalent: PPMT. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.Rate(numPeriods int, pmt float64, pv float64, fv float64, paymentType int, guess float64) float64, error` Rate returns the periodic interest rate for a cash flow with constant periodic payments (annuities). Guess is a guess for the rate, used as a starting point for the iterative algorithm. Excel equivalent: RATE. "paymentType" must be one of: 0 = PayEnd, 1 = PayBegin. #### `func finance.TBillEquivalentYield(settlement int64, maturity int64, discount float64) float64, error` TBillEquivalentYield returns the bond-equivalent yield for a Treasury bill. "settlement" is the unix timestamp (seconds) for the settlement date. "maturity" is the unix timestamp (seconds) for the maturity date. "discount" is the T-Bill discount rate. Excel equivalent: TBILLEQ. #### `func finance.TBillPrice(settlement int64, maturity int64, discount float64) float64, error` TBillPrice returns the price per $100 face value for a Treasury bill. "settlement" is the unix timestamp (seconds) for the settlement date. "maturity" is the unix timestamp (seconds) for the maturity date. "discount" is the T-Bill discount rate. Excel equivalent: TBILLPRICE. #### `func finance.TBillYield(settlement int64, maturity int64, price float64) float64, error` TBillYield returns the yield for a treasury bill. "settlement" is the unix timestamp (seconds) for the settlement date. "maturity" is the unix timestamp (seconds) for the maturity date. "price" is the TBill price per $100 face value. Excel equivalent: TBILLYIELD. ### hex #### `func hex.EncodeToString(src []byte) string` EncodeToString returns the hexadecimal encoding of src. #### `func hex.DecodeString(s string) []byte, error` DecodeString returns the bytes represented by the hexadecimal string s. DecodeString expects that src contains only hexadecimal characters and that src has even length. If the input is malformed, DecodeString returns the bytes decoded before the error. ### html #### `func html.EscapeString(s string) string` EscapeString escapes special characters like "<" to become "<". It escapes only five such characters: <, >, &, ' and ". `UnescapeString`(EscapeString(s)) == s always holds, but the converse isn't always true. #### `func html.UnescapeString(s string) string` UnescapeString unescapes entities like "<" to become "<". It unescapes a larger range of entities than `EscapeString` escapes. For example, "á" unescapes to "á", as does "á" and "á". UnescapeString(`EscapeString`(s)) == s always holds, but the converse isn't always true. ### json #### `func json.Marshal(v any) []byte, error` Marshal returns the JSON encoding of v. Marshal traverses the value v recursively. If an encountered value implements `Marshaler` and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] to produce JSON. If no [Marshaler.MarshalJSON] method is present but the value implements [encoding.TextMarshaler] instead, Marshal calls [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. The nil pointer exception is not strictly necessary but mimics a similar, necessary exception in the behavior of [Unmarshaler.UnmarshalJSON]. Otherwise, Marshal uses the following type-dependent default encodings: Boolean values encode as JSON booleans. Floating point, integer, and `Number` values encode as JSON numbers. NaN and +/-Inf values will return an `UnsupportedValueError`. String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune. So that the JSON will be safe to embed inside HTML tags, the string is encoded using `HTMLEscape`, which replaces "<", ">", "&", U+2028, and U+2029 are escaped to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". This replacement can be disabled when using an `Encoder`, by calling `Encoder.SetEscapeHTML(false)`. Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value. Struct values encode as JSON objects. Each exported struct field becomes a member of the object, using the field name as the object key, unless the field is omitted for one of the reasons given below. The encoding of each struct field can be customized by the format string stored under the "json" key in the struct field's tag. The format string gives the name of the field, possibly followed by a comma-separated list of options. The name may be empty in order to specify options without overriding the default field name. The "omitempty" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any array, slice, map, or string of length zero. As a special case, if the field tag is "-", the field is always omitted. Note that a field with name "-" can still be generated using the tag "-,". Examples of struct field tags and their meanings: ``` // Field appears in JSON as key "myName". Field int `json:"myName"` // Field appears in JSON as key "myName" and // the field is omitted from the object if its value is empty, // as defined above. Field int `json:"myName,omitempty"` // Field appears in JSON as key "Field" (the default), but // the field is skipped if empty. // Note the leading comma. Field int `json:",omitempty"` // Field is ignored by this package. Field int `json:"-"` // Field appears in JSON as key "-". Field int `json:"-,"` ``` The "omitzero" option specifies that the field should be omitted from the encoding if the field has a zero value, according to rules: 1) If the field type has an "IsZero() bool" method, that will be used to determine whether the value is zero. 2) Otherwise, the value is zero if it is the zero value for its type. If both "omitempty" and "omitzero" are specified, the field will be omitted if the value is either empty or zero (or both). The "string" option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs: ``` Int64String int64 `json:",string"` ``` The key name will be used if it's a non-empty string consisting of only Unicode letters, digits, and ASCII punctuation except quotation marks, backslash, and comma. Embedded struct fields are usually marshaled as if their inner exported fields were fields in the outer struct, subject to the usual Go visibility rules amended as described in the next paragraph. An anonymous struct field with a name given in its JSON tag is treated as having that name, rather than being anonymous. An anonymous struct field of interface type is treated the same as having that type as its name, rather than being anonymous. The Go visibility rules for struct fields are amended for JSON when deciding which field to marshal or unmarshal. If there are multiple fields at the same level, and that level is the least nested (and would therefore be the nesting level selected by the usual Go rules), the following extra rules apply: 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, even if there are multiple untagged fields that would otherwise conflict. 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 3) Otherwise there are multiple fields, and all are ignored; no error occurs. Handling of anonymous struct fields is new in Go 1.1. Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of an anonymous struct field in both current and earlier versions, give the field a JSON tag of "-". Map values encode as JSON objects. The map's key type must either be a string, an integer type, or implement [encoding.TextMarshaler]. The map keys are sorted and used as JSON object keys by applying the following rules, subject to the UTF-8 coercion described for string values above: - keys of any string type are used directly - keys that implement [encoding.TextMarshaler] are marshaled - integer keys are converted to strings Pointer values encode as the value pointed to. A nil pointer encodes as the null JSON value. Interface values encode as the value contained in the interface. A nil interface value encodes as the null JSON value. Channel, complex, and function values cannot be encoded in JSON. Attempting to encode such a value causes Marshal to return an `UnsupportedTypeError`. JSON cannot represent cyclic data structures and Marshal does not handle them. Passing cyclic structures to Marshal will result in an error. #### `func json.Marshal(v any) []byte, error` Marshal returns the JSON encoding of v. Marshal traverses the value v recursively. The input value is encoded as JSON according the following rules: - If the value type implements [jsonv2.MarshalerTo], then the MarshalJSONTo method is called to encode the value. If the method returns [errors.ErrUnsupported], then the input is encoded according to subsequent rules. - If the value type implements `Marshaler`, then the MarshalJSON method is called to encode the value. - If the value type implements [encoding.TextAppender], then the AppendText method is called to encode the value and subsequently encode its result as a JSON string. - If the value type implements [encoding.TextMarshaler], then the MarshalText method is called to encode the value and subsequently encode its result as a JSON string. Otherwise, Marshal uses the following type-dependent default encodings: Boolean values encode as JSON booleans. Floating point, integer, and `Number` values encode as JSON numbers. NaN and +/-Inf values will return an `UnsupportedValueError`. String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune. So that the JSON will be safe to embed inside HTML tags, the string is encoded using `HTMLEscape`, which replaces "<", ">", "&", U+2028, and U+2029 are escaped to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". This replacement can be disabled when using an `Encoder`, by calling `Encoder.SetEscapeHTML(false)`. Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value. Struct values encode as JSON objects. Each exported struct field becomes a member of the object, using the field name as the object key, unless the field is omitted for one of the reasons given below. The encoding of each struct field can be customized by the format string stored under the "json" key in the struct field's tag. The format string gives the name of the field, possibly followed by a comma-separated list of options. The name may be empty in order to specify options without overriding the default field name. The "omitempty" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any array, slice, map, or string of length zero. As a special case, if the field tag is "-", the field is always omitted. JSON names containing commas or quotes, or names identical to "" or "-", can be specified using a single-quoted string literal, where the syntax is identical to the Go grammar for a double-quoted string literal, but instead uses single quotes as the delimiters. Examples of struct field tags and their meanings: ``` // Field appears in JSON as key "myName". Field int `json:"myName"` // Field appears in JSON as key "myName" and // the field is omitted from the object if its value is empty, // as defined above. Field int `json:"myName,omitempty"` // Field appears in JSON as key "Field" (the default), but // the field is skipped if empty. // Note the leading comma. Field int `json:",omitempty"` // Field is ignored by this package. Field int `json:"-"` // Field appears in JSON as key "-". Field int `json:"'-'"` ``` The "omitzero" option specifies that the field should be omitted from the encoding if the field has a zero value, according to rules: 1) If the field type has an "IsZero() bool" method, that will be used to determine whether the value is zero. 2) Otherwise, the value is zero if it is the zero value for its type. If both "omitempty" and "omitzero" are specified, the field will be omitted if the value is either empty or zero (or both). The "string" option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs: ``` Int64String int64 `json:",string"` ``` The key name will be used if it's a non-empty string consisting of only Unicode letters, digits, and ASCII punctuation except quotation marks, backslash, and comma. Embedded struct fields are usually marshaled as if their inner exported fields were fields in the outer struct, subject to the usual Go visibility rules amended as described in the next paragraph. An anonymous struct field with a name given in its JSON tag is treated as having that name, rather than being anonymous. An anonymous struct field of interface type is treated the same as having that type as its name, rather than being anonymous. The Go visibility rules for struct fields are amended for JSON when deciding which field to marshal or unmarshal. If there are multiple fields at the same level, and that level is the least nested (and would therefore be the nesting level selected by the usual Go rules), the following extra rules apply: 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, even if there are multiple untagged fields that would otherwise conflict. 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 3) Otherwise there are multiple fields, and all are ignored; no error occurs. Handling of anonymous struct fields is new in Go 1.1. Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of an anonymous struct field in both current and earlier versions, give the field a JSON tag of "-". Map values encode as JSON objects. The map's key type must either be a string, an integer type, or implement [encoding.TextMarshaler]. The map keys are sorted and used as JSON object keys by applying the following rules, subject to the UTF-8 coercion described for string values above: - keys of any string type are used directly - keys that implement [encoding.TextMarshaler] are marshaled - integer keys are converted to strings Pointer values encode as the value pointed to. A nil pointer encodes as the null JSON value. Interface values encode as the value contained in the interface. A nil interface value encodes as the null JSON value. Channel, complex, and function values cannot be encoded in JSON. Attempting to encode such a value causes Marshal to return an `UnsupportedTypeError`. JSON cannot represent cyclic data structures and Marshal does not handle them. Passing cyclic structures to Marshal will result in an error. ### math #### `func math.Abs(x float64) float64` Abs returns the absolute value of x. Special cases are: ``` Abs(±Inf) = +Inf Abs(NaN) = NaN ``` #### `func math.Cbrt(x float64) float64` Cbrt returns the cube root of x. Special cases are: ``` Cbrt(±0) = ±0 Cbrt(±Inf) = ±Inf Cbrt(NaN) = NaN ``` #### `func math.Copysign(f float64, sign float64) float64` Copysign returns a value with the magnitude of f and the sign of sign. #### `func math.Dim(x float64, y float64) float64` Dim returns the maximum of x-y or 0. Special cases are: ``` Dim(+Inf, +Inf) = NaN Dim(-Inf, -Inf) = NaN Dim(x, NaN) = Dim(NaN, x) = NaN ``` #### `func math.Max(x float64, y float64) float64` Max returns the larger of x or y. Special cases are: ``` Max(x, +Inf) = Max(+Inf, x) = +Inf Max(x, NaN) = Max(NaN, x) = NaN Max(+0, ±0) = Max(±0, +0) = +0 Max(-0, -0) = -0 ``` Note that this differs from the built-in function max when called with NaN and +Inf. #### `func math.Min(x float64, y float64) float64` Min returns the smaller of x or y. Special cases are: ``` Min(x, -Inf) = Min(-Inf, x) = -Inf Min(x, NaN) = Min(NaN, x) = NaN Min(-0, ±0) = Min(±0, -0) = -0 ``` Note that this differs from the built-in function min when called with NaN and -Inf. #### `func math.Exp(x float64) float64` Exp returns e**x, the base-e exponential of x. Special cases are: ``` Exp(+Inf) = +Inf Exp(NaN) = NaN ``` Very large values overflow to 0 or +Inf. Very small values underflow to 1. #### `func math.Exp2(x float64) float64` Exp2 returns 2**x, the base-2 exponential of x. Special cases are the same as `Exp`. #### `func math.Expm1(x float64) float64` Expm1 returns e**x - 1, the base-e exponential of x minus 1. It is more accurate than `Exp`(x) - 1 when x is near zero. Special cases are: ``` Expm1(+Inf) = +Inf Expm1(-Inf) = -1 Expm1(NaN) = NaN ``` Very large values overflow to -1 or +Inf. #### `func math.Floor(x float64) float64` Floor returns the greatest integer value less than or equal to x. Special cases are: ``` Floor(±0) = ±0 Floor(±Inf) = ±Inf Floor(NaN) = NaN ``` #### `func math.Ceil(x float64) float64` Ceil returns the least integer value greater than or equal to x. Special cases are: ``` Ceil(±0) = ±0 Ceil(±Inf) = ±Inf Ceil(NaN) = NaN ``` #### `func math.Trunc(x float64) float64` Trunc returns the integer value of x. Special cases are: ``` Trunc(±0) = ±0 Trunc(±Inf) = ±Inf Trunc(NaN) = NaN ``` #### `func math.Round(x float64) float64` Round returns the nearest integer, rounding half away from zero. Special cases are: ``` Round(±0) = ±0 Round(±Inf) = ±Inf Round(NaN) = NaN ``` #### `func math.RoundToEven(x float64) float64` RoundToEven returns the nearest integer, rounding ties to even. Special cases are: ``` RoundToEven(±0) = ±0 RoundToEven(±Inf) = ±Inf RoundToEven(NaN) = NaN ``` #### `func math.FMA(x float64, y float64, z float64) float64` FMA returns x * y + z, computed with only one rounding. (That is, FMA returns the fused multiply-add of x, y, and z.) #### `func math.Hypot(p float64, q float64) float64` Hypot returns `Sqrt`(p*p + q*q), taking care to avoid unnecessary overflow and underflow. Special cases are: ``` Hypot(±Inf, q) = +Inf Hypot(p, ±Inf) = +Inf Hypot(NaN, q) = NaN Hypot(p, NaN) = NaN ``` #### `func math.Log(x float64) float64` Log returns the natural logarithm of x. Special cases are: ``` Log(+Inf) = +Inf Log(0) = -Inf Log(x < 0) = NaN Log(NaN) = NaN ``` #### `func math.Log10(x float64) float64` Log10 returns the decimal logarithm of x. The special cases are the same as for `Log`. #### `func math.Log2(x float64) float64` Log2 returns the binary logarithm of x. The special cases are the same as for `Log`. #### `func math.Log1p(x float64) float64` Log1p returns the natural logarithm of 1 plus its argument x. It is more accurate than `Log`(1 + x) when x is near zero. Special cases are: ``` Log1p(+Inf) = +Inf Log1p(±0) = ±0 Log1p(-1) = -Inf Log1p(x < -1) = NaN Log1p(NaN) = NaN ``` #### `func math.Mod(x float64, y float64) float64` Mod returns the floating-point remainder of x/y. The magnitude of the result is less than y and its sign agrees with that of x. Special cases are: ``` Mod(±Inf, y) = NaN Mod(NaN, y) = NaN Mod(x, 0) = NaN Mod(x, ±Inf) = x Mod(x, NaN) = NaN ``` #### `func math.Pow(x float64, y float64) float64` Pow returns x**y, the base-x exponential of y. Special cases are (in order): ``` Pow(x, ±0) = 1 for any x Pow(1, y) = 1 for any y Pow(x, 1) = x for any x Pow(NaN, y) = NaN Pow(x, NaN) = NaN Pow(±0, y) = ±Inf for y an odd integer < 0 Pow(±0, -Inf) = +Inf Pow(±0, +Inf) = +0 Pow(±0, y) = +Inf for finite y < 0 and not an odd integer Pow(±0, y) = ±0 for y an odd integer > 0 Pow(±0, y) = +0 for finite y > 0 and not an odd integer Pow(-1, ±Inf) = 1 Pow(x, +Inf) = +Inf for |x| > 1 Pow(x, -Inf) = +0 for |x| > 1 Pow(x, +Inf) = +0 for |x| < 1 Pow(x, -Inf) = +Inf for |x| < 1 Pow(+Inf, y) = +Inf for y > 0 Pow(+Inf, y) = +0 for y < 0 Pow(-Inf, y) = Pow(-0, -y) Pow(x, y) = NaN for finite x < 0 and finite non-integer y ``` #### `func math.Pow10(n int) float64` Pow10 returns 10**n, the base-10 exponential of n. Special cases are: ``` Pow10(n) = 0 for n < -323 Pow10(n) = +Inf for n > 308 ``` #### `func math.Remainder(x float64, y float64) float64` Remainder returns the IEEE 754 floating-point remainder of x/y. Special cases are: ``` Remainder(±Inf, y) = NaN Remainder(NaN, y) = NaN Remainder(x, 0) = NaN Remainder(x, ±Inf) = x Remainder(x, NaN) = NaN ``` #### `func math.Signbit(x float64) bool` Signbit reports whether x is negative or negative zero. #### `func math.Sqrt(x float64) float64` Sqrt returns the square root of x. Special cases are: ``` Sqrt(+Inf) = +Inf Sqrt(±0) = ±0 Sqrt(x < 0) = NaN Sqrt(NaN) = NaN ``` ### md5 #### `func md5.Sum(data []byte) []byte` Sum returns the MD5 checksum of the data. ### money #### `func money.Add(a money, b money) money, error` Add two Money types and return the result #### `func money.Sub(a money, b money) money, error` Compute the difference between two Money types #### `func money.Mul(a money, b string) money, error` Multiply a Money type by a string-represented number #### `func money.Div(a money, b string) money, error` Divide a Money type by a string-represented number ### path #### `func path.Clean(path string) string` Clean returns the shortest path name equivalent to path by purely lexical processing. It applies the following rules iteratively until no further processing can be done: 1. Replace multiple slashes with a single slash. 2. Eliminate each . path name element (the current directory). 3. Eliminate each inner .. path name element (the parent directory) along with the non-.. element that precedes it. 4. Eliminate .. elements that begin a rooted path: that is, replace "/.." by "/" at the beginning of a path. The returned path ends in a slash only if it is the root "/". If the result of this process is an empty string, Clean returns the string ".". See also Rob Pike, “Lexical File Names in Plan 9 or Getting Dot-Dot Right,” https://9p.io/sys/doc/lexnames.html #### `func path.Ext(path string) string` Ext returns the file name extension used by path. The extension is the suffix beginning at the final dot in the final slash-separated element of path; it is empty if there is no dot. #### `func path.Base(path string) string` Base returns the last element of path. Trailing slashes are removed before extracting the last element. If the path is empty, Base returns ".". If the path consists entirely of slashes, Base returns "/". #### `func path.IsAbs(path string) bool` IsAbs reports whether the path is absolute. #### `func path.Dir(path string) string` Dir returns all but the last element of path, typically the path's directory. After dropping the final element using `Split`, the path is Cleaned and trailing slashes are removed. If the path is empty, Dir returns ".". If the path consists entirely of slashes followed by non-slash bytes, Dir returns a single slash. In any other case, the returned path does not end in a slash. ### rand #### `func rand.Int63() int64` Int63 returns a non-negative pseudo-random 63-bit integer as an int64 from the default `Source`. #### `func rand.Uint32() uint32` Uint32 returns a pseudo-random 32-bit value as a uint32 from the default `Source`. #### `func rand.Uint64() uint64` Uint64 returns a pseudo-random 64-bit value as a uint64 from the default `Source`. #### `func rand.Int31() int32` Int31 returns a non-negative pseudo-random 31-bit integer as an int32 from the default `Source`. #### `func rand.Int() int` Int returns a non-negative pseudo-random int from the default `Source`. #### `func rand.Int63n(n int64) int64` Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n) from the default `Source`. It panics if n <= 0. #### `func rand.Int31n(n int32) int32` Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n) from the default `Source`. It panics if n <= 0. #### `func rand.Intn(n int) int` Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n) from the default `Source`. It panics if n <= 0. #### `func rand.Float64() float64` Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0) from the default `Source`. #### `func rand.Float32() float32` Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0) from the default `Source`. #### `func rand.NormFloat64() float64` NormFloat64 returns a normally distributed float64 in the range [-[math.MaxFloat64], +[math.MaxFloat64]] with standard normal distribution (mean = 0, stddev = 1) from the default `Source`. To produce a different normal distribution, callers can adjust the output using: ``` sample = NormFloat64() * desiredStdDev + desiredMean ``` #### `func rand.ExpFloat64() float64` ExpFloat64 returns an exponentially distributed float64 in the range (0, +[math.MaxFloat64]] with an exponential distribution whose rate parameter (lambda) is 1 and whose mean is 1/lambda (1) from the default `Source`. To produce a distribution with a different rate parameter, callers can adjust the output using: ``` sample = ExpFloat64() / desiredRateParameter ``` ### sha1 #### `func sha1.Sum(data []byte) []byte` Sum returns the SHA-1 checksum of the data. ### sha256 #### `func sha256.Sum256(data []byte) []byte` Sum256 returns the SHA256 checksum of the data. ### sha512 #### `func sha512.Sum512(data []byte) []byte` Sum512 returns the SHA512 checksum of the data. ### strings #### `func strings.Compare(a string, b string) int` Compare returns an integer comparing two strings lexicographically. The result will be 0 if a == b, -1 if a < b, and +1 if a > b. Use Compare when you need to perform a three-way comparison (with [slices.SortFunc], for example). It is usually clearer and always faster to use the built-in string comparison operators ==, <, >, and so on. #### `func strings.Count(s string, substr string) int` Count counts the number of non-overlapping instances of substr in s. If substr is an empty string, Count returns 1 + the number of Unicode code points in s. #### `func strings.Contains(s string, substr string) bool` Contains reports whether substr is within s. #### `func strings.ContainsAny(s string, chars string) bool` ContainsAny reports whether any Unicode code points in chars are within s. #### `func strings.LastIndex(s string, substr string) int` LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s. #### `func strings.IndexAny(s string, chars string) int` IndexAny returns the index of the first instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s. #### `func strings.LastIndexAny(s string, chars string) int` LastIndexAny returns the index of the last instance of any Unicode code point from chars in s, or -1 if no Unicode code point from chars is present in s. #### `func strings.HasPrefix(s string, prefix string) bool` HasPrefix reports whether the string s begins with prefix. #### `func strings.HasSuffix(s string, suffix string) bool` HasSuffix reports whether the string s ends with suffix. #### `func strings.Repeat(s string, count int) string` Repeat returns a new string consisting of count copies of the string s. It panics if count is negative or if the result of (len(s) * count) overflows. #### `func strings.ToUpper(s string) string` ToUpper returns s with all Unicode letters mapped to their upper case. #### `func strings.ToLower(s string) string` ToLower returns s with all Unicode letters mapped to their lower case. #### `func strings.ToTitle(s string) string` ToTitle returns a copy of the string s with all Unicode letters mapped to their Unicode title case. #### `func strings.ToValidUTF8(s string, replacement string) string` ToValidUTF8 returns a copy of the string s with each run of invalid UTF-8 byte sequences replaced by the replacement string, which may be empty. #### `func strings.Title(s string) string` Title returns a copy of the string s with all Unicode letters that begin words mapped to their Unicode title case. Deprecated: The rule Title uses for word boundaries does not handle Unicode punctuation properly. Use golang.org/x/text/cases instead. #### `func strings.Trim(s string, cutset string) string` Trim returns a slice of the string s with all leading and trailing Unicode code points contained in cutset removed. #### `func strings.TrimLeft(s string, cutset string) string` TrimLeft returns a slice of the string s with all leading Unicode code points contained in cutset removed. To remove a prefix, use `TrimPrefix` instead. #### `func strings.TrimRight(s string, cutset string) string` TrimRight returns a slice of the string s, with all trailing Unicode code points contained in cutset removed. To remove a suffix, use `TrimSuffix` instead. #### `func strings.TrimSpace(s string) string` TrimSpace returns a slice (substring) of the string s, with all leading and trailing white space removed, as defined by Unicode. #### `func strings.TrimPrefix(s string, prefix string) string` TrimPrefix returns s without the provided leading prefix string. If s doesn't start with prefix, s is returned unchanged. #### `func strings.TrimSuffix(s string, suffix string) string` TrimSuffix returns s without the provided trailing suffix string. If s doesn't end with suffix, s is returned unchanged. #### `func strings.Replace(s string, old string, new string, n int) string` Replace returns a copy of the string s with the first n non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string. If n < 0, there is no limit on the number of replacements. #### `func strings.ReplaceAll(s string, old string, new string) string` ReplaceAll returns a copy of the string s with all non-overlapping instances of old replaced by new. If old is empty, it matches at the beginning of the string and after each UTF-8 sequence, yielding up to k+1 replacements for a k-rune string. #### `func strings.EqualFold(s string, t string) bool` EqualFold reports whether s and t, interpreted as UTF-8 strings, are equal under simple Unicode case-folding, which is a more general form of case-insensitivity. #### `func strings.Index(s string, substr string) int` Index returns the index of the first instance of substr in s, or -1 if substr is not present in s. ### url #### `func url.QueryEscape(s string) string` QueryEscape escapes the string so it can be safely placed inside a `URL` query. #### `func url.PathEscape(s string) string` PathEscape escapes the string so it can be safely placed inside a `URL` path segment, replacing special characters (including /) with %XX sequences as needed. ### uuid #### `func uuid.New() uuid` New creates a new random UUID. #### `func uuid.NewMD5(space uuid, data []byte) uuid` NewMD5 returns a new MD5 (Version 3) UUID based on the supplied name space and data. #### `func uuid.NewSHA1(space uuid, data []byte) uuid` NewSHA1 returns a new SHA1 (Version 5) UUID based on the supplied name space and data. #### `func uuid.Zero() uuid` Zero returns the zero uuid('00000000-0000-0000-0000-000000000000') --- # CEL Reference Embedded computation with the common expression language runtime. Twisp uses the [Common Expression Language](https://github.com/google/cel-spec) extensively for computation. Anywhere the Expression type is used in GraphQL, a CEL expression is accepted and will be evaluated at runtime. - [Variables Reference](https://www.twisp.com/docs/reference/cel/variables.md): Context variables available in indexes, calculations, and tran codes. - [Functions and Examples](https://www.twisp.com/docs/reference/cel/examples.md): Comprehensive examples of functions provided by the runtime. - [Functions](https://www.twisp.com/docs/reference/cel/functions.md): Standard library functions provided by the runtime. --- # CEL Variables Reference Context variables available in CEL expressions across Twisp APIs. Twisp uses [Common Expression Language](https://cel.dev/) extensively for computation across the API. Different contexts expose different variables depending on their purpose. This reference documents what variables are available in each context. ## Overview | Context | Primary Variable | Description | |-------------------------------|------------------|---------------------------------| | [Indexes](https://www.twisp.com/docs/reference/cel/variables.md#indexes) | `document` | The record being indexed | | [Calculations](https://www.twisp.com/docs/reference/cel/variables.md#calculations) | `context.vars` | Transaction and account context | | [Tran Codes](https://www.twisp.com/docs/reference/cel/variables.md#tran-codes) | `params` | Post-time parameters | --- ## Indexes Custom indexes use CEL expressions to define partition keys, sort keys, and filter constraints. In all index expressions, the primary variable is `document`, which represents the record being indexed. ### Available Variables | Variable | Type | Description | |------------|------------------|--------------------------| | `document` | Protobuf message | The entity being indexed | The type of `document` depends on the `on` field specified when creating the index: - `ACCOUNT` → [Account](https://www.twisp.com/docs/reference/cel/variables.md#account-fields) - `ACCOUNT_SET` → [AccountSet](https://www.twisp.com/docs/reference/cel/variables.md#account-set-fields) - `TRANSACTION` → [Transaction](https://www.twisp.com/docs/reference/cel/variables.md#transaction-fields) - `TRANCODE` → [TranCode](https://www.twisp.com/docs/reference/cel/variables.md#trancode-fields) - `BALANCE` → [Balance](https://www.twisp.com/docs/reference/cel/variables.md#balance-fields) - `ENTRY` → [Entry](https://www.twisp.com/docs/reference/cel/variables.md#entry-fields) ### Partition Expressions Partition keys determine how records are grouped in the index. ```graphql mutation CreatePartitionedIndex { schema { createIndex( input: { name: "entries_by_account" on: Entry partition: [ { alias: "accountId", value: "document.account_id" } { alias: "journalId", value: "document.journal_id" } ] } ) { name } } } ``` Partition expressions can return arrays to create multiple index entries. For example this create multiple partitions for the account id and each of it's parent account sets (at time of posting): ```graphql partition: [ { alias: "accountId", value: "document.parent_account_ids + [document.account_id]" } ] ``` ### Sort Expressions Sort keys define the ordering within each partition. In this example sorting either by th ```graphql mutation CreateSortedIndex { schema { createIndex( input: { name: "entries_by_effective" on: Entry partition: [{ alias: "accountId", value: "document.account_id" }] sort: [ { alias: "effective" value: "'effective' in document.metadata && document.metadata.effective != null ? document.metadata.effective : document.created" type: STRING sort: DESC } ] } ) { name } } } ``` ### Filter Constraints Constraints are boolean expressions that must all evaluate to `true` for a record to be included in the index. ```graphql mutation CreateFilteredIndex { schema { createIndex( input: { name: "active_entries" on: Entry partition: [{ alias: "accountId", value: "document.account_id" }] constraints: { isNotVoidEntry: "!document.is_void_entry" isNotVoidedEntry: "!document.is_voided_entry" isSettled: "document.layer == SETTLED" } } ) { name } } } ``` --- ## Calculations Calculations define how balances are computed and grouped. CEL expressions are used in dimension definitions and conditions. > **Note:** > > **Expressions must resolve to a concrete type.** When you call `createCalculation`, each dimension expression is evaluated against an example record so its storage type can be inferred, and the `condition` expression must resolve to a boolean. Paths that reach into `dyn` JSON fields — like `context.vars.account.metadata.*` or `context.vars.entry.metadata.*` — won't resolve on their own. Two ways to fix this: > > - **Cast the result**: `string(context.vars.account.metadata.region)`, `int(context.vars.entry.metadata.score)`, `bool(context.vars.account.metadata.verified)`. > - **Provide a typed fallback** with optional access: `context.vars.account.?metadata.orValue({}).?region.orValue('')` resolves to a string even when `metadata.region` is missing. > > The same rule applies to `condition` — it must resolve to a `bool`. Use `bool(...)` or `.orValue(false)` if your expression reaches into untyped metadata. ### Available Variables | Variable | Type | Description | |----------|------|-------------| | `context.vars.transaction` | [Transaction](https://www.twisp.com/docs/reference/cel/variables.md#transaction-fields) | The parent transaction of the entry | | `context.vars.account` | [Account](https://www.twisp.com/docs/reference/cel/variables.md#account-fields) | The account the entry is posted to | | `document` | [Entry](https://www.twisp.com/docs/reference/cel/variables.md#entry-fields) | The entry being evaluated (in conditions) | ### Dimension Expressions Dimensions define how balances are grouped. Common use cases include grouping by date, metadata values, or account properties. ```graphql mutation CreateEffectiveDateCalculation { createCalculation( input: { calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5" code: "EFFECTIVE_DATE" description: "Track balances per effective date." dimensions: [ { alias: "effectiveDate" value: "context.vars.transaction.effective" } ] scope: LOCAL } ) { calculationId code } } ``` Multi-dimensional calculations: ```graphql mutation CreateMultiDimensionCalculation { createCalculation( input: { calculationId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" code: "BY_CURRENCY_AND_DATE" description: "Track balances by currency and effective date." dimensions: [ { alias: "currency" value: "string(context.vars.account.metadata.currency)" } { alias: "effectiveDate" value: "context.vars.transaction.effective" } ] scope: LOCAL } ) { calculationId } } ``` ### Condition Expressions Conditions filter which entries are included in the calculation. They must evaluate to a boolean. ```graphql mutation CreateConditionalCalculation { createCalculation( input: { calculationId: "b2c3d4e5-f6a7-8901-bcde-f23456789012" code: "POLICY_PAYMENTS" description: "Track only entries to accounts with policy payment metadata." dimensions: [ { alias: "effectiveDate", value: "context.vars.transaction.effective" } ] condition: "has(context.vars.account.metadata.policyPayment)" scope: LOCAL } ) { calculationId } } ``` Using entry fields in conditions: ```graphql condition: "document.layer == 0 && document.direction == 0" ``` --- ## Tran Codes Tran codes are templates that define how transactions and entries are created. CEL expressions are used extensively to dynamically compute values at post time. ### Available Variables | Variable | Type | Description | |----------|------|-------------| | `params` | Struct | Parameters passed when posting the transaction | | `vars` | Struct | Calculated variables defined in the tran code's `vars` field | ### Parameter Access Parameters are defined in the tran code and passed at post time. Access them with `params.`: ```graphql mutation CreateTranCode { createTranCode( input: { code: "TRANSFER" description: "Transfer funds between accounts" params: [ { name: "amount", type: TYPE_DECIMAL, description: "Transfer amount" } { name: "fromAccount", type: TYPE_UUID, description: "Source account" } { name: "toAccount", type: TYPE_UUID, description: "Destination account" } { name: "memo", type: TYPE_STRING, default: "'Transfer'", description: "Optional memo" } ] transaction: { description: "'Transfer ' + string(params.amount) + ' - ' + params.memo" } entries: [ { entryType: "'TRANSFER_DR'" accountId: "params.fromAccount" direction: "'DEBIT'" units: "params.amount" currency: "'USD'" } { entryType: "'TRANSFER_CR'" accountId: "params.toAccount" direction: "'CREDIT'" units: "params.amount" currency: "'USD'" } ] } ) { code } } ``` ### Vars (Scratch Pad) The `vars` field provides a scratch pad for intermediate calculations. Variables defined here can be referenced in transaction and entry expressions: ```graphql mutation CreateTranCodeWithVars { createTranCode( input: { code: "TRANSFER_WITH_FEE" description: "Transfer with calculated fee" params: [ { name: "amount", type: TYPE_DECIMAL } { name: "fromAccount", type: TYPE_UUID } { name: "toAccount", type: TYPE_UUID } { name: "feeAccount", type: TYPE_UUID } ] vars: { feeRate: "'0.025'" feeAmount: "decimal(params.amount) * decimal(vars.feeRate)" netAmount: "decimal(params.amount) - vars.feeAmount" } entries: [ { entryType: "'TRANSFER_DR'" accountId: "params.fromAccount" direction: "'DEBIT'" units: "params.amount" currency: "'USD'" } { entryType: "'TRANSFER_CR'" accountId: "params.toAccount" direction: "'CREDIT'" units: "vars.netAmount" currency: "'USD'" } { entryType: "'FEE_CR'" accountId: "params.feeAccount" direction: "'CREDIT'" units: "vars.feeAmount" currency: "'USD'" } ] } ) { code } } ``` ### Entry Conditions Entry conditions determine whether an entry should be created. Useful for optional entries: ```graphql entries: [ { entryType: "'FEE'" accountId: "params.feeAccount" direction: "'CREDIT'" units: "params.feeAmount" currency: "'USD'" condition: "params.feeAmount > decimal('0.00')" } ] ``` ### Transaction Fields All fields in the `transaction` block accept CEL expressions: | Field | Expected Type | Example | |-------|--------------|---------| | `journalId` | UUID | `"uuid('b28f5684-0834-4292-8016-d2f2fb0367a9')"` | | `correlationId` | String | `"params.correlationId"` | | `externalId` | String | `"params.externalId"` | | `effective` | Date | `"date('2024-01-15')"` or `"params.effectiveDate"` | | `description` | String | `"'Payment: ' + string(params.amount)"` | | `metadata` | JSON | `"{ 'source': 'api', 'amount': string(params.amount) }"` | ### Entry Fields All fields in each entry accept CEL expressions: | Field | Expected Type | Example | |-------|--------------|---------| | `entryType` | String | `"'ACH_CREDIT'"` | | `accountId` | UUID | `"params.accountId"` | | `layer` | Enumeration | `"SETTLED"` or `"PENDING"` or `"ENCUMBRANCE"` | | `direction` | Enumeration | `"DEBIT"` or `"CREDIT"` | | `units` | Decimal | `"params.amount"` or `"decimal('100.00')"` | | `currency` | String | `"'USD'"` or `"params.currency"` | | `description` | String | `"'Entry for ' + params.memo"` | | `metadata` | CEL Map/JSON | `"{ 'lineItem': params.lineItem }"` | | `condition` | Boolean | `"params.amount > decimal('0')"` | --- ## Entity Field Reference ### Account Fields | Field | Type | Description | |-------|------|-------------| | `account_id` | UUID | Unique identifier | | `status` | Enum | ACTIVE, LOCKED, or INACTIVE | | `name` | String | Account name | | `code` | String | Shorthand code | | `normal_balance_type` | Enum | DEBIT (0) or CREDIT (1) | | `description` | String | Account description | | `metadata` | Struct | Arbitrary JSON data | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | | `external_id` | String | External system identifier | ### Account Set Fields | Field | Type | Description | |-------|------|-------------| | `account_set_id` | UUID | Unique identifier | | `journal_id` | UUID | Associated journal | | `account_id` | UUID | Associated account ID | | `name` | String | Set name | | `description` | String | Set description | | `metadata` | Struct | Arbitrary JSON data | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | | `code` | String | Unique code | | `has_members` | Boolean | True once the set has ever contained a member; never reset — not a current-emptiness check | ### Transaction Fields | Field | Type | Description | |-------|------|-------------| | `transaction_id` | UUID | Unique identifier | | `tran_code_id` | UUID | Associated tran code | | `journal_id` | UUID | Associated journal | | `correlation_id` | String | Groups related transactions | | `external_id` | String | External system identifier | | `effective` | Date | Accounting effective date | | `description` | String | Transaction description | | `metadata` | Struct | Arbitrary JSON data | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | ### Entry Fields | Field | Type | Description | |-------|------|-------------| | `entry_id` | UUID | Unique identifier | | `transaction_id` | UUID | Parent transaction | | `journal_id` | UUID | Associated journal | | `account_id` | UUID | Target account | | `entry_type` | String | Entry type code | | `layer` | Enum | SETTLED (0), PENDING (1), or ENCUMBRANCE (2) | | `direction` | Enum | DEBIT (0) or CREDIT (1) | | `description` | String | Entry description | | `amount` | Money | Entry amount with currency | | `metadata` | Struct | Arbitrary JSON data | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | | `parent_account_ids` | List[UUID] | Parent account set IDs | | `is_void_entry` | Boolean | True if this is a voiding entry | | `is_voided_entry` | Boolean | True if this entry was voided | ### TranCode Fields | Field | Type | Description | |-------|------|-------------| | `tran_code_id` | UUID | Unique identifier | | `code` | String | Unique code identifier | | `description` | String | Tran code description | | `status` | Enum | ACTIVE, LOCKED, or INACTIVE | | `params` | List | Parameter definitions | | `transaction` | Struct | Transaction template | | `entries` | List | Entry templates | | `metadata` | Struct | Arbitrary JSON data | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | ### Balance Fields | Field | Type | Description | |-------|------|-------------| | `journal_id` | UUID | Associated journal | | `account_id` | UUID | Associated account | | `transaction_id` | UUID | Last transaction | | `entry_id` | UUID | Last entry | | `currency` | String | Currency code | | `settled` | BalanceAmount | Settled layer balance | | `pending` | BalanceAmount | Pending layer balance | | `encumbrance` | BalanceAmount | Encumbrance layer balance | | `created` | Timestamp | Creation time | | `modified` | Timestamp | Last modification time | | `calculation_id` | UUID | Associated calculation | | `dimensions` | Struct | Dimension values | --- ## Type Constructors When working with CEL expressions, use these constructors to create typed values: | Constructor | Example | Description | |------------|---------|-------------| | `uuid(string)` | `uuid('a1b2c3d4-...')` | Parse UUID from string | | `decimal(string)` | `decimal('100.50')` | High-precision decimal | | `money(string, string)` | `money('100.00', 'USD')` | Money with currency | | `date(string)` | `date('2024-01-15')` | Parse date (YYYY-MM-DD) | | `timestamp(string)` | `timestamp('2024-01-15T10:30:00Z')` | Parse ISO 8601 timestamp | | `bool(string)` | `bool('true')` | Parse boolean | | `int(string)` | `int('42')` | Parse integer | | `string(any)` | `string(params.amount)` | Convert to string | For a complete list of functions, see the [CEL Functions Reference](https://www.twisp.com/docs/reference/cel/examples.md). --- # Directives Directives provide a way to add metadata and modify the behavior of GraphQL operations, fields, and types. ## @cel Denotes that the variable definition is resolved via a CEL Expression. The default value provided to the string is the CEL expression. And the cel value must resolve/convert to the graphql type indicated by the variable. @example(`$someVariable: String = "string('hello world')" @cel`) #### Locations ``VARIABLE_DEFINITION`` ## @deprecated Marks an element of a GraphQL schema as no longer supported. #### Arguments --- * ``reason`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax, as specified by [CommonMark](https://commonmark.org/). _Default:_ ``"No longer supported"`` #### Locations ``FIELD_DEFINITION``, ``ARGUMENT_DEFINITION``, ``INPUT_FIELD_DEFINITION``, ``ENUM_VALUE``, ``DIRECTIVE_DEFINITION`` ## @dryRun Allows to dryRun a mutation without committing the data. #### Locations ``MUTATION`` ## @export #### Arguments --- * ``as`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``cel`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A literal CEL expression to be evaluated. #### Locations ``FIELD`` ## @include Directs the executor to include this field or fragment only when the `if` argument is true. #### Arguments --- * ``if`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Included when true. #### Locations ``FIELD``, ``FRAGMENT_SPREAD``, ``INLINE_FRAGMENT`` ## @oneOf Indicates exactly one field must be supplied and this field must not be `null`. #### Locations ``INPUT_OBJECT`` ## @retry Twisp will retry retriable errors for up to duration automatically. Uses a golang duration string. If the value is less than or equal to zero, no retries performed. @example(`@retry(for:"30s")`) #### Arguments --- * ``for`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. _Default:_ ``"30s"`` #### Locations ``MUTATION``, ``QUERY`` ## @skip Directs the executor to skip this field or fragment when the `if` argument is true. #### Arguments --- * ``if`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Skipped when true. #### Locations ``FIELD``, ``FRAGMENT_SPREAD``, ``INLINE_FRAGMENT`` ## @specifiedBy Exposes a URL that specifies the behavior of this scalar. #### Arguments --- * ``url`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The URL that specifies the behavior of this scalar. #### Locations ``SCALAR`` ## @tx Sets the transaction isolation level for the operation. @example(`@tx(isolation: SERIALIZABLE)`) #### Arguments --- * ``isolation`` - [`TxIsolation`](https://www.twisp.com/docs/reference/graphql/types/enum.md#tx-isolation) * Transaction isolation level. Different isolation levels provide different guarantees about data visibility and consistency. _Default:_ ``SNAPSHOT`` #### Locations ``MUTATION``, ``QUERY`` --- # GraphQL API Reference Documentation for the Twisp GraphQL API. The primary way to interact with the [Accounting Core](https://www.twisp.com/docs/accounting-core.md) is through the GraphQL API. Use this reference to learn about the full GraphQL Schema. - [Queries](https://www.twisp.com/docs/reference/graphql/queries.md): Retrieve data from the system. - [Mutations](https://www.twisp.com/docs/reference/graphql/mutations.md): Modify or create data on the system. - [Directives](https://www.twisp.com/docs/reference/graphql/directives.md): Add metadata and modify behavior of operations. - [Object Types](https://www.twisp.com/docs/reference/graphql/types/object.md): The primary data model for responses. - [Input Types](https://www.twisp.com/docs/reference/graphql/types/input.md): Arguments for mutations and queries. - [Enum Types](https://www.twisp.com/docs/reference/graphql/types/enum.md): Set of predefined values for a field. - [Scalar Types](https://www.twisp.com/docs/reference/graphql/types/scalar.md): Primitive values for fields. - [Interface Types](https://www.twisp.com/docs/reference/graphql/types/interface.md): Set of fields that object types can implement. - [Union Types](https://www.twisp.com/docs/reference/graphql/types/union.md): Combinations of two or more object types. --- # Mutations Mutations modify or create data on the ledger or execute admin actions by specifying the operation to be performed and the input data. ## ach ### createConfiguration Create a configuration for processing an ACH file. Defines settlement exception and suspense accounts. Defines the endpoint that decisioning webhooks are sent to for this configuration. #### Resolves to [`AchConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) #### Arguments --- * ``input`` - [`AchCreateConfigurationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-create-configuration-input) * **Request** ```graphql mutation CreateConfiguration { ach { createConfiguration( input: { configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" exceptionAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" feeAccountId: "62808a87-0b11-4dce-8877-767b70f029af" journalId: "00000000-0000-0000-0000-000000000000" odfiHeaderConfiguration: { immediateDestination: "026009593" immediateDestinationName: "ACME BANK" immediateOrigin: "231380104" immediateOriginName: "ZUZU" } timeZone: "America/Los_Angeles" } ) { configId } } } ``` **Response** ```json { "data": { "ach": { "createConfiguration": { "configId": "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" } } } } ``` ### generateFile Generate an ACH file. Currently only generates RDFI return files. #### Resolves to [`AchGeneratedFile!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-generated-file) #### Arguments --- * ``input`` - [`AchGenerateFileInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-generate-file-input) * **Request** ```graphql mutation GenerateFile { ach { generateFile( input: { configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" fileKey: "return.ach" fileType: RDFI_RETURN options: { fileHeaderReferenceCode: "REF00001" } } ) { fileKey } } } ``` **Response** ```json { "data": { "ach": { "generateFile": { "fileKey": "return.ach" } } } } ``` ### processFile Process an ACH file at the file key with the defined configuration. #### Resolves to [`AchProcessedFile!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-processed-file) #### Arguments --- * ``input`` - [`AchProcessFileInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-process-file-input) * **Request** ```graphql mutation ProcessFile { ach { processFile( input: { configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" fileKey: "ppd-credit.ach" fileType: RDFI } ) { fileId } } } ``` **Response** ```json { "data": { "ach": { "processFile": { "fileId": "b0d76a9a-afcd-4b1b-b115-01b88d7b84e6" } } } } ``` ### updateConfiguration Update an ACH configuration. #### Resolves to [`AchConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) #### Arguments --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``input`` - [`AchUpdateConfigurationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-update-configuration-input) * **Request** ```graphql mutation UpdateConfiguration { ach { updateConfiguration( configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" input: { timeZone: "America/Chicago" traceNumberConfiguration: { minTraceNumber: 5000000 maxTraceNumber: 9999999 } fileModifierConfiguration: { startFileIdModifier: "B" endFileIdModifier: "9" } } ) { configId timeZone traceNumberConfiguration { minTraceNumber maxTraceNumber } fileModifierConfiguration { startFileIdModifier endFileIdModifier userSupplied } version } } } ``` **Response** ```json { "data": { "ach": { "updateConfiguration": { "configId": "1dc71d60-f463-4bb6-b82a-ab42e2f923ff", "timeZone": "America/Chicago", "traceNumberConfiguration": { "minTraceNumber": 5000000, "maxTraceNumber": 9999999 }, "fileModifierConfiguration": { "startFileIdModifier": "B", "endFileIdModifier": "9", "userSupplied": false }, "version": 2 } } } } ``` ## addLimitToControl Add a limit to the control. #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The control to add limit to. --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The velocity limit to add. ## addToAccountSet Add a new member to a set. Members can be an Account or another AccountSet; the declared member type must match the member's actual configuration. The member's existing balance is backfilled into the target set and every ancestor set that becomes newly reachable through this edge; a set already reachable via another path is not seeded twice. An AccountSet member must be empty when it is added — its future members contribute to every ancestor through their own additions. Non-concurrent sets backfill synchronously in this call. Concurrent sets seed the balance immediately and finish settling asynchronously over a bounded window (typically ~1-2 minutes; see `Account.setMembershipStatuses`). While a previous membership change for the same (set, member) is still settling, a re-add is rejected — retry after it resolves. For new accounts, prefer `createAccount` with `accountSetIds`: a same-transaction create-and-add is active immediately and takes no write intents on set rows. A funded add takes write intents on the target set and any non-concurrent ancestors, so funded adds into the same set — or sharing a non-concurrent ancestor — serialize and surface retryable ABORTED conflicts under churn; different sets under a shared concurrent rollup stay parallel. #### Resolves to [`AccountSet!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for set. --- * ``member`` - [`AccountSetMemberInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-member-input) * Account or AccountSet to add as a member of this set. **Request** ```graphql mutation AddToAccountSet( $accountSetCustomersId: UUID! $accountCustomerAliciaId: UUID! ) { addToAccountSet( id: $accountSetCustomersId member: { memberId: $accountCustomerAliciaId, memberType: ACCOUNT } ) { accountSetId members(first: 10) { nodes { ... on Account { accountId name code } } } } } ``` **Response** ```json { "data": { "addToAccountSet": { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "members": { "nodes": [ { "accountId": "260fd651-8819-4f99-9c8a-87d27e03ee4c", "name": "Alicia", "code": "CUST.Alicia" } ] } } } } ``` **Variables** ```json { "accountSetCustomersId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "accountCustomerAliciaId": "260fd651-8819-4f99-9c8a-87d27e03ee4c" } ``` ## admin Mutations in the `admin` namespace are used to manage the organization data like users, groups, and tenants. ### branch Copy the selected configuration entities from the current tenant into a new tenant with a randomly generated `accountId`. `include` selects the entity classes to copy; when you omit it, `branch` copies every class. Unlike the other `admin` mutations, `branch` may be called from any region. The tenant record is always created in the SSO region; the configuration copy always happens in the calling region. Configuration is copied as-is, so identifiers, timestamps and endpoint signing secrets are preserved. No account, balance, transaction or entry data is copied. The default journal and the default clients are created by tenant creation itself; your own clients are always copied. #### Resolves to [`Tenant`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) #### Arguments --- * ``input`` - [`BranchInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#branch-input) * ### createAlias Create a new tenant alias in the current region. Requires `db:Insert` on `financial.aliases`. #### Resolves to [`Alias`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias) #### Arguments --- * ``input`` - [`CreateAliasInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-alias-input) * Fields to create a new alias. ### createGroup Create a new group. #### Resolves to [`Group`](https://www.twisp.com/docs/reference/graphql/types/object.md#group) #### Arguments --- * ``input`` - [`CreateGroupInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-group-input) * Fields to create a new group. **Request** ```graphql 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 } } } ``` **Response** ```json { "data": { "admin": { "createGroup": { "name": "empty-policy-1", "description": "A group with an empty policy", "policy": "[]" } } } } ``` ### createTenant Create a new tenant. #### Resolves to [`Tenant`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) #### Arguments --- * ``input`` - [`CreateTenantInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-tenant-input) * Fields to create a new tenant. **Request** ```graphql mutation AdminCreateTenant { admin { createTenant( input: { id: "72a0097f-239e-48ec-a417-49c318332ed6" accountId: "sandbox" name: "Sandbox" description: "Sandbox tenant for testing" ephemeral: true } ) { accountId name created ephemeral } } } ``` **Response** ```json { "data": { "admin": { "createTenant": { "accountId": "sandbox", "name": "Sandbox", "created": "2000-01-01T00:00:00Z", "ephemeral": true } } } } ``` ### createUser Create a new human user. Upon creation, new users will receive an invite email to sign in to Twisp Console. #### Resolves to [`User`](https://www.twisp.com/docs/reference/graphql/types/object.md#user) #### Arguments --- * ``input`` - [`CreateUserInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-user-input) * Fields to create a new user. **Request** ```graphql mutation AdminCreateUser { admin { createUser( input: { id: "9cc8bd28-a36d-502e-89fd-7f1410c1b90a" groupIds: ["d57bd759-73d5-4452-a73e-12b590324e35"] email: "george@twisp.com" } ) { id email groupIds } } } ``` **Response** ```json { "data": { "admin": { "createUser": { "id": "9cc8bd28-a36d-502e-89fd-7f1410c1b90a", "email": "george@twisp.com", "groupIds": ["d57bd759-73d5-4452-a73e-12b590324e35"] } } } } ``` ### deleteAlias Delete an existing tenant alias. Only the organization that created the alias may delete it. #### Resolves to [`Alias`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias) #### Arguments --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Alias to delete. ### deleteGroup Delete an existing group. #### Resolves to [`Group`](https://www.twisp.com/docs/reference/graphql/types/object.md#group) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of group to delete. **Request** ```graphql mutation AdminDeleteGroup { admin { deleteGroup(name: "empty-policy-1") { name } } } ``` **Response** ```json { "data": { "admin": { "deleteGroup": { "name": "empty-policy-1" } } } } ``` ### deleteTenant Delete an existing tenant. #### Resolves to [`Tenant`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) #### Arguments --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier. **Request** ```graphql mutation AdminDeleteTenant { admin { deleteTenant(accountId: "sandbox") { accountId } } } ``` **Response** ```json { "data": { "admin": { "deleteTenant": { "accountId": "sandbox" } } } } ``` ### deleteUser Delete an existing human user. #### Resolves to [`User`](https://www.twisp.com/docs/reference/graphql/types/object.md#user) #### Arguments --- * ``email`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Email of user to delete. **Request** ```graphql mutation AdminDeleteUser { admin { deleteUser(email: "george@twisp.com") { email } } } ``` **Response** ```json { "data": { "admin": { "deleteUser": { "email": "george@twisp.com" } } } } ``` ### restore Restore a tenant/region into a new tenant/region #### Resolves to [`RestoreOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#restore-output) #### Arguments --- * ``input`` - [`RestoreInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#restore-input) * ### updateAlias Update an existing tenant alias. Only the organization that created the alias may update it. #### Resolves to [`Alias`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias) #### Arguments --- * ``input`` - [`UpdateAliasInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-alias-input) * Fields to update. ### updateGroup Update an existing group. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Group`](https://www.twisp.com/docs/reference/graphql/types/object.md#group) #### Arguments --- * ``input`` - [`UpdateGroupInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-group-input) * Fields to update. **Request** ```graphql 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 } } } ``` **Response** ```json { "data": { "admin": { "updateGroup": { "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\"}}]" } } } } ``` ### updateTenant Update an existing tenant. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Tenant`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) #### Arguments --- * ``input`` - [`UpdateTenantInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-tenant-input) * Fields to update. **Request** ```graphql mutation AdminUpdateTenant { admin { updateTenant( input: { accountId: "sandbox" description: "This is the sandbox tenant." } ) { accountId description version } } } ``` **Response** ```json { "data": { "admin": { "updateTenant": { "accountId": "sandbox", "description": "This is the sandbox tenant.", "version": 2 } } } } ``` ### updateUser Update an existing human user. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`User`](https://www.twisp.com/docs/reference/graphql/types/object.md#user) #### Arguments --- * ``input`` - [`UpdateUserInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-user-input) * Fields to update. **Request** ```graphql mutation AdminUpdateUser { admin { updateUser( input: { email: "george@twisp.com" groupIds: ["152f0c89-6cba-53c9-955e-16d7cbc1f35e"] } ) { email groupIds } } } ``` **Response** ```json { "data": { "admin": { "updateUser": { "email": "george@twisp.com", "groupIds": ["152f0c89-6cba-53c9-955e-16d7cbc1f35e"] } } } } ``` ## attachCalculation Attaches a calculation to an account or account set for entries on the specified journal. #### Resolves to [`AttachedCalculation!`](https://www.twisp.com/docs/reference/graphql/types/object.md#attached-calculation) #### Arguments --- * ``input`` - [`AttachCalculationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#attach-calculation-input) * **Request** ```graphql mutation AttachCalculation { attachCalculation( input: { accountId: "260fd651-8819-4f99-9c8a-87d27e03ee4c" calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5" journalId: "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ) { calculationId } } ``` **Response** ```json { "data": { "attachCalculation": { "calculationId": "5867b5dd-fc69-416c-80f5-62e8a53610d5" } } } ``` ## attachVelocityControl Attach an account or set to the control. #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The control to attach account limit to. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account or Set Id to attach to the velocity control to. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal on which journal to attach the velocity control to. Attaches to the default journal if not provided. --- * ``params`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The parameters for the velocity limit to use. If attaching for default limits for control (`velocityLimitId == null`), Then params must satify all defined params on defualt limits **Request** ```graphql mutation AttachVelocityControl( $velocityControlId: UUID! = "f6f27892-dfd8-480b-9213-d6adf7ef04ef" $aliciaAccountId: UUID! = "260fd651-8819-4f99-9c8a-87d27e03ee4c" $journalId: UUID! = "822cb59f-ce51-4837-8391-2af3b7a5fc51" $limit: Decimal = "1000.00" ) { attachVelocityControl( velocityControlId: $velocityControlId accountId: $aliciaAccountId journalId: $journalId params: { amount: $limit } ) { velocityControlId } } ``` **Response** ```json { "data": { "attachVelocityControl": { "velocityControlId": "f6f27892-dfd8-480b-9213-d6adf7ef04ef" } } } ``` ## 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!`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) #### Arguments --- * ``input`` - [`CreateClientInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-client-input) * **Request** ```graphql 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 } } } ``` **Response** ```json { "data": { "auth": { "createClient": { "principal": "arn:aws:iam::048962233173:user/github.action" } } } } ``` **Variables** ```json { "authClientGithub": "arn:aws:iam::048962233173:user/github.action" } ``` ### deleteClient Delete a security client. #### Resolves to [`Client`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) #### Arguments --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Principal to delete. **Request** ```graphql mutation DeleteAuthClient($authClientGithub: String!) { auth { deleteClient(principal: $authClientGithub) { principal } } } ``` **Response** ```json { "data": { "auth": { "deleteClient": { "principal": "arn:aws:iam::048962233173:user/github.action" } } } } ``` **Variables** ```json { "authClientGithub": "arn:aws:iam::048962233173:user/github.action" } ``` ### updateClient Update an existing client by replacing policies. #### Resolves to [`Client`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) #### Arguments --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Principal of the client to update. --- * ``input`` - [`UpdateClientInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-client-input) * Client fields to update. **Request** ```graphql 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 } } } } ``` **Response** ```json { "data": { "auth": { "updateClient": { "policies": [ { "effect": "ALLOW", "actions": ["SELECT", "INSERT"], "resources": ["financial.*"], "assertions": { "isTrue": "true" } } ] } } } } ``` **Variables** ```json { "authClientGithub": "arn:aws:iam::048962233173:user/github.action" } ``` ## bulk ### cancelExecution Request cancellation of a running bulk query execution. Returns immediately with `stopping: true` if a cancellation request was sent. Note: there is a race condition between requesting cancellation and the execution completing on its own. The execution may finish (successfully or with an error) before the cancellation takes effect. Use the `execution` query to poll for the final status. #### Resolves to [`CancelBulkQueryExecutionResult`](https://www.twisp.com/docs/reference/graphql/types/object.md#cancel-bulk-query-execution-result) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ### execute #### Resolves to [`BulkQueryExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution) #### Arguments --- * ``input`` - [`BulkQueryInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#bulk-query-input) * ## cards Mutations in the `cards` namespace are used to initialize card processing transaction codes, including specific implementations like the Lithic card processing webhook. ### initializeCardTransactionCodes DEPRECATED: Use Lithic workflow in workflow namespace. Initialize your Twisp instance with Card Processing Transaction Codes. Returns the default settlement account. #### Resolves to [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) #### Arguments --- * ``input`` - [`CardInitializeInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#card-initialize-input) * **Request** ```graphql mutation InitializeCardTransactionCodes($journalGLId: UUID!) { cards { initializeCardTransactionCodes(input: { journalId: $journalGLId }) { accountId name code } } } ``` **Response** ```json { "data": { "cards": { "initializeCardTransactionCodes": { "accountId": "f8c3b0a4-e0f7-4057-aced-7030c0eb918a", "name": "Card Settlement Account", "code": "Liabilities.Settlement.Card" } } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ### postLithicTransaction DEPRECATED: Use Lithic workflow in workflow namespace. This mutation supports converting Lithic [Transaction Webhooks JSON](https://docs.lithic.com/docs/transaction-webhooks#schema) 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!`](https://www.twisp.com/docs/reference/graphql/types/object.md#lithic-transaction-balance) #### Arguments --- * ``input`` - [`LithicTransactionInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#lithic-transaction-input) * ## createAccount Create a new account. #### Resolves to [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) #### Arguments --- * ``input`` - [`AccountInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-input) * Fields to create a new account. **Request** ```graphql 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 } } ``` **Response** ```json { "data": { "createAccount": { "accountId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8", "name": "Card Settlement", "code": "SETTLE.CARD", "description": "Settlement account for card transactions.", "normalBalanceType": "CREDIT" } } } ``` **Variables** ```json { "accountCardSettlementId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8" } ``` ## createAccountSet Create a new account set. #### Resolves to [`AccountSet!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``input`` - [`AccountSetInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-input) * Fields to create a new account set. **Request** ```graphql mutation CreateAccountSet($accountSetCustomersId: UUID!, $journalGLId: UUID!) { createAccountSet( input: { accountSetId: $accountSetCustomersId journalId: $journalGLId name: "Customers" description: "All customer wallets." normalBalanceType: DEBIT } ) { accountSetId name description code } } ``` **Response** ```json { "data": { "createAccountSet": { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "name": "Customers", "description": "All customer wallets.", "code": "Ke8_GJexQNmYUifxYHtsqIIstZ_OUUg3g5Eq87el_FE" } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "accountSetCustomersId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8" } ``` ## createCalculation Create a calculation, which allows for balances to be customized on dimensions/filters. #### Resolves to [`Calculation!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) #### Arguments --- * ``input`` - [`CreateCalculationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-calculation-input) * **Request** ```graphql 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" } ] scope: LOCAL } ) { calculationId code description scope dimensions { alias value } } } ``` **Response** ```json { "data": { "createCalculation": { "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" } ], "scope": "LOCAL" } } } ``` ## createJournal Create a new journal for recording transactions in the ledger. #### Resolves to [`Journal!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) #### Arguments --- * ``input`` - [`JournalInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#journal-input) * Fields to create a new Journal. **Request** ```graphql mutation CreateJournal($journalGLId: UUID!) { createJournal( input: { journalId: $journalGLId name: "GL" description: "General Ledger" status: ACTIVE } ) { journalId name description status } } ``` **Response** ```json { "data": { "createJournal": { "journalId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "name": "GL", "description": "General Ledger", "status": "ACTIVE" } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ## createTranCode Create a new transaction code (tran code). #### Resolves to [`TranCode!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) #### Arguments --- * ``input`` - [`TranCodeInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-input) * Fields to create a new TranCode. **Request** ```graphql 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." } ] vars: { amount2: "decimal('1.00')", amount3: "this.amount2" } 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 } } ``` **Response** ```json { "data": { "createTranCode": { "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855" } } } ``` **Variables** ```json { "journalGLIdExp": "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')", "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855" } ``` ## createVelocityControl #### Resolves to [`VelocityControl!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``input`` - [`VelocityControlInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-control-input) * **Request** ```graphql mutation CreateVelocityControl { createVelocityControl( input: { velocityControlId: "f6f27892-dfd8-480b-9213-d6adf7ef04ef" name: "Example Control" description: """ Example control that rejects transactions unless transaction metadata explictly disables enforcement of control. """ condition: "context.vars.transaction.?metadata.disableVelocityControl.orValue(false) == false" enforcement: { action: REJECT } } ) { velocityControlId name } } ``` **Response** ```json { "data": { "createVelocityControl": { "velocityControlId": "f6f27892-dfd8-480b-9213-d6adf7ef04ef", "name": "Example Control" } } } ``` ## createVelocityLimit #### Resolves to [`VelocityLimit!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) #### Arguments --- * ``input`` - [`VelocityLimitInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-limit-input) * **Request** ```graphql mutation CreateVelocityLimit { createVelocityLimit( input: { velocityLimitId: "370ac19b-a48c-4480-9b1f-18c39d214a0a" name: "Example Monthly Limit" description: """ A per month spending limit at the ENCUMBRANCE layer. """ window: [ { alias: "year", value: "context.vars.transaction.effective.getYear()" } { alias: "month" value: "context.vars.transaction.effective.getMonth()" } ] currency: "USD" limit: { balance: [ { layer: "ENCUMBRANCE" amount: "params.amount" normalBalanceType: "DEBIT" } ] } params: [ { name: "amount" type: DECIMAL description: """ Aggregate spend up to amount per effective month. Defaults to $100.00 """ default: "100.00" } ] # Add to existing velocity control velocityControlIds: ["f6f27892-dfd8-480b-9213-d6adf7ef04ef"] } ) { velocityLimitId } } ``` **Response** ```json { "data": { "createVelocityLimit": { "velocityLimitId": "370ac19b-a48c-4480-9b1f-18c39d214a0a" } } } ``` ## 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`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteAccount($accountCustomerBobbyId: UUID!) { deleteAccount(id: $accountCustomerBobbyId) { accountId status } } ``` **Response** ```json { "data": { "deleteAccount": { "accountId": "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b", "status": "LOCKED" } } } ``` **Variables** ```json { "accountCustomerBobbyId": "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b" } ``` ## deleteAccountSet Soft-delete an account set. This is mark-only: it always succeeds and marks the set `DELETED`, regardless of whether the set still has members. It does not remove members, does not detach the set from its parents, and does not change any balance — a deleted set that still sits under a parent keeps contributing until its members are removed. A deleted set can no longer be added to another set or accept new members, and the mark is permanent (there is no un-delete). To remove a deleted set from its parents, empty it and then detach it with `removeFromAccountSet` once its drain window has passed. #### Resolves to [`AccountSet`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteAccountSet($accountSetCustomersId: UUID!) { deleteAccountSet(id: $accountSetCustomersId) { accountSetId } } ``` **Response** ```json { "data": { "deleteAccountSet": { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8" } } } ``` **Variables** ```json { "accountSetCustomersId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8" } ``` ## deleteCalculation " Delete calculation sets calculation to `LOCKED`. If in attached scope, must remove all attachments first. #### Resolves to [`Calculation`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteCalculation { deleteCalculation(id: "5867b5dd-fc69-416c-80f5-62e8a53610d5") { calculationId status } } ``` **Response** ```json { "data": { "deleteCalculation": { "calculationId": "5867b5dd-fc69-416c-80f5-62e8a53610d5", "status": "LOCKED" } } } ``` ## deleteJournal Moves journal into `LOCKED` status. Prevents entries from being posted to the journal. #### Resolves to [`Journal`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteJournal($journalGLId: UUID!) { deleteJournal(id: $journalGLId) { journalId status } } ``` **Response** ```json { "data": { "deleteJournal": { "journalId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "status": "LOCKED" } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ## deleteTranCode Moves the tran code into `LOCKED` status. Prevents transactions from posting using this version of tran code. #### Resolves to [`TranCode`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteTranCode($tcBookTransferId: UUID!) { deleteTranCode(id: $tcBookTransferId) { tranCodeId status } } ``` **Response** ```json { "data": { "deleteTranCode": { "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855", "status": "LOCKED" } } } ``` **Variables** ```json { "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855" } ``` ## deleteVelocityControl #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## deleteVelocityLimit #### Resolves to [`VelocityLimit`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) #### Arguments --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## detachCalculation Removes calculation from attachment. #### Resolves to [`AttachedCalculation`](https://www.twisp.com/docs/reference/graphql/types/object.md#attached-calculation) #### Arguments --- * ``input`` - [`DetachCalculationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#detach-calculation-input) * **Request** ```graphql mutation DetachCalculation { detachCalculation( input: { accountId: "260fd651-8819-4f99-9c8a-87d27e03ee4c" calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5" journalId: "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ) { calculationId } } ``` **Response** ```json { "data": { "detachCalculation": { "calculationId": "5867b5dd-fc69-416c-80f5-62e8a53610d5" } } } ``` ## detachVelocityControl detach account from control. #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The Velocity Control to detach. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The account id detaching from. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The journal detaching from. If not provided this will detach from default journal. ## evaluate Evaluate a CEL (common expression language) expression using Twisp's calculation engine. Returns a String representation of the evaluated result. #### Resolves to [`Value!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#value) #### Arguments --- * ``expressions`` - [`ExpressionNestedMap!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-nested-map) * A nested 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()", "obj": { "foo": "'bar'" } } --- * ``document`` - [`Value`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#value) * Value object. Similar to the JSON object with support for type coersion **Request** ```graphql 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)" j: "context.auth" k: "decimal('-inf')" l: "string(decimal('-inf'))" m: { n: "document.this" } o: "this.m.n" } document: { greeting: "Hello" uuid: $id upper: $uppercase expr: $expression this: $this nonCEL: $nonCEL celNonCEL: $celNonCEL } ) } ``` **Response** ```json { "data": { "evaluate": { "a": 1, "b": "Hello World!", "c": "0.246912679", "d": 456, "e": 36, "f": "JOHN DOE", "g": 4, "h": "JOHN DOE", "i": "NOT CEL", "j": { "claims": { "twisp_policy_layers": "W1t7ImVmZmVjdCI6IkFMTE9XIiwiYWN0aW9ucyI6WyIqIl0sInJlc291cmNlcyI6WyIqIl19XV0=" }, "policies": [ { "actions": ["*"], "effect": 1, "resources": ["*"] } ], "principal": "test" }, "k": "-Infinity", "l": "-Infinity", "m": { "n": "JOHN DOE" }, "o": "JOHN DOE" } } } ``` **Variables** ```json { "lowercase": "john doe", "expression": "2 * 2", "nonCEL": "not cel" } ``` ## events Queries in the `events` namespace retrieve event data, such as webhooks. ### createEndpoint Create a new endpoint. #### Resolves to [`Endpoint!`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) #### Arguments --- * ``input`` - [`EndpointInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#endpoint-input) * Fields to create a new endpoint. **Request** ```graphql 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 } } } ``` **Response** ```json { "data": { "events": { "createEndpoint": { "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "status": "ENABLED", "endpointType": "WEBHOOK", "url": "https://webhook.site/twisp-webhook-test", "subscription": ["balance*", "account.*"], "description": "subscribe to balance and account events" } } } } ``` ### deleteEndpoint #### Resolves to [`Endpoint`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql mutation DeleteEndpoint { events { deleteEndpoint(id: "345940ed-2726-4b20-88aa-820857ac0e68") { endpointId status endpointType url subscription description } } } ``` **Response** ```json { "data": { "events": { "deleteEndpoint": { "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "status": "DISABLED", "endpointType": "WEBHOOK", "url": "https://webhook.site/updated-webhook-test", "subscription": ["account.*"], "description": "updated status" } } } } ``` ### updateEndpoint Update fields on an existing account. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Endpoint`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`EndpointUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#endpoint-update-input) * Fields to update. **Request** ```graphql mutation UpdateEndpoint { events { updateEndpoint( id: "345940ed-2726-4b20-88aa-820857ac0e68" input: { status: DISABLED url: "https://webhook.site/updated-webhook-test" description: "updated status" subscription: ["account.*"] filters: { isTrue: "true" } } ) { endpointId status endpointType url subscription description filters } } } ``` **Response** ```json { "data": { "events": { "updateEndpoint": { "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "status": "DISABLED", "endpointType": "WEBHOOK", "url": "https://webhook.site/updated-webhook-test", "subscription": ["account.*"], "description": "updated status", "filters": { "isTrue": "true" } } } } } ``` ## files ### createDownload Create a link to download a file. #### Resolves to [`Download`](https://www.twisp.com/docs/reference/graphql/types/object.md#download) #### Arguments --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. **Request** ```graphql mutation CreateDownload { files { createDownload(key: "some-file.json") { downloadURL } } } ``` **Response** ```json { "data": { "files": { "createDownload": { "downloadURL": "http://localhost:8080/files?tenant=REDACTED&key=some-file.json" } } } } ``` ### createUpload Create a file upload. #### Resolves to [`Upload`](https://www.twisp.com/docs/reference/graphql/types/object.md#upload) #### Arguments --- * ``input`` - [`CreateUpload!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-upload) * ## iso8583 ### createConfig Create a configuration for ISO8583 processing. Defines settlement account, journal, and timezone. #### Resolves to [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) #### Arguments --- * ``input`` - [`ISO8583CreateConfigInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#iso8583create-config-input) * **Request** ```graphql # Create a journal and settlement account first before creating config mutation CreateISO8583Config { # Create the ISO8583 config iso8583 { createConfig( input: { configId: "670504f6-0515-11f0-a441-069b540ea27c" journalId: "8b65c8dc-0515-11f0-a441-069b540ea27c" settlementAccountId: "779886bc-0515-11f0-aa78-069b540ea27c" timeZone: "America/Chicago" description: "Primary ISO8583 processor configuration" processor: I2C } ) { configId journalId settlementAccountId timeZone description processor version } } } ``` **Response** ```json { "data": { "iso8583": { "createConfig": { "configId": "670504f6-0515-11f0-a441-069b540ea27c", "journalId": "8b65c8dc-0515-11f0-a441-069b540ea27c", "settlementAccountId": "779886bc-0515-11f0-aa78-069b540ea27c", "timeZone": "America/Chicago", "description": "Primary ISO8583 processor configuration", "processor": "I2C", "version": 1 } } } } ``` ### deleteConfig Remove configuration. #### Resolves to [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ### updateConfig Update configuration for ISO8583 processing. #### Resolves to [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) #### Arguments --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``input`` - [`ISO8583UpdateConfigInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#iso8583update-config-input) * ## kv Namespace for transactional key/value mutations. ### delete Delete a KV record by its `(namespace, key)` natural key. Optional `conditions` run against the current record, with `document` and `value` bound to it — or `null` when no record exists. The delete proceeds only if all conditions evaluate to `true`. #### Resolves to [`KVValue`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) #### Arguments --- * ``namespace`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``conditions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * 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()" } **Request** ```graphql mutation DeleteKv { kv { delete(namespace: "flags", key: "feature-a") { namespace key description value } } } ``` **Response** ```json { "data": { "kv": { "delete": { "namespace": "flags", "key": "feature-a", "description": "feature flag a", "value": { "enabled": false, "rollout": 50, "owner": "risk" } } } } } ``` ### put Create or replace a KV record. Writes a new version on every call. Limits: - `namespace`: max 512 UTF-8 bytes - `key`: max 512 UTF-8 bytes - persisted payload (`description` + serialized `value`): max 256 KiB #### Resolves to [`KVValue!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) #### Arguments --- * ``input`` - [`KVPutInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#kvput-input) * **Request** ```graphql mutation PutKv { kv { put( input: { namespace: "flags" key: "feature-a" description: "feature flag a" value: { enabled: true, rollout: 25, owner: "risk" } } ) { namespace key description value version } } } ``` **Response** ```json { "data": { "kv": { "put": { "namespace": "flags", "key": "feature-a", "description": "feature flag a", "value": { "enabled": true, "rollout": 25, "owner": "risk" }, "version": 1 } } } } ``` ### update Evaluate an expression value against the existing KV `value` and merge the result in using RFC 7396 semantics. String leaves are CEL expressions; non-string leaves are literal patch values. `value` and `document` in the expression context both refer to the existing KV `value`. Fails with NOT_FOUND when no record exists for `(namespace, key)`. #### Resolves to [`KVValue!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) #### Arguments --- * ``input`` - [`KVUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#kvupdate-input) * **Request** ```graphql mutation UpdateKv { kv { update( input: { namespace: "flags" key: "feature-a" expressions: { enabled: false, rollout: "value.rollout + 25" } conditions: { current_rollout: "document.value.rollout == 25" } } ) { namespace key description value version conditions } } } ``` **Response** ```json { "data": { "kv": { "update": { "namespace": "flags", "key": "feature-a", "description": "feature flag a", "value": { "enabled": false, "rollout": 50, "owner": "risk" }, "version": 2, "conditions": { "current_rollout": "document.value.rollout == 25" } } } } } ``` ## postTransaction Write a transaction to the ledger using the predefined defaults from the `tranCode` provided. #### Resolves to [`Transaction!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) #### Arguments --- * ``input`` - [`TransactionInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-input) * Fields to post a new Transaction. **Request** ```graphql 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 } } ``` **Response** ```json { "data": { "postTransaction": { "transactionId": "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68" } } } ``` **Variables** ```json { "accountCustomerAliciaId": "260fd651-8819-4f99-9c8a-87d27e03ee4c", "accountCustomerBobbyId": "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b" } ``` ## queries #### Resolves to [`Query!`](https://www.twisp.com/docs/reference/graphql/types/object.md#query) #### Arguments ## removeAllLimitsFromControl Remove all limits from the velocity control. #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The control to remove from. ## removeFromAccountSet Remove a member from a set. The member's contribution is reversed out of the target set and every ancestor set that becomes unreachable by removing this edge. Account members are removed normally. Removing an **account set** member (detaching a sub-set) is restricted, because a set's structure is append-only while it is in use: a sub-set that has ever held a member is frozen and cannot be detached — reorganize by creating a new set instead of moving a populated one. The one exception is a sub-set that has been soft-deleted (see `deleteAccountSet`): once it is physically empty and past its drain window it may be detached from each parent. Attempting that detach before the drain window closes returns a **retriable** error whose `retryAfter` extension is the instant to retry at; attempting it while the sub-set still has members is rejected outright (empty it first). Non-concurrent sets reverse synchronously in this call. Concurrent sets reverse immediately and settle the change over a bounded window, during which re-adding the member is rejected (see `Account.setMembershipStatuses`). #### Resolves to [`AccountSet!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for set. --- * ``member`` - [`AccountSetMemberInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-member-input) * Account or AccountSet to remove from this set. ## removeLimitFromControl Remove a single limit from control. #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The control to remove from. --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The velocity limit to remove. ## scheduler Mutations in the `scheduler` namespace are used to manage scheduled jobs ### createSchedule #### Resolves to [`Schedule`](https://www.twisp.com/docs/reference/graphql/types/object.md#schedule) #### Arguments --- * ``input`` - [`CreateScheduleInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-schedule-input) * Fields to create a new schedule. ## schema Mutations in the `schema` namespace are used to manage custom indexes, aggregates, and historical indexes. Use the `schema` namespace to create and delete indexes and aggregates. ### createHistoricalIndex Create a custom index for querying all versions of records' histories. Because the Twisp FLDB is an [immutable, append-only data store](https://www.twisp.com/docs/infrastructure/ledger-database.md#append-only-immutability), 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!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``input`` - [`CreateIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-index-input) * ### 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](mailto:support@twisp.com). To learn more about indexes within the Twisp FLDB, see [Index-First Design](https://www.twisp.com/docs/infrastructure/ledger-database.md#index-first-design) in the docs. #### Resolves to [`Index!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``input`` - [`CreateIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-index-input) * **Request** ```graphql 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 } } } ``` **Response** ```json { "data": { "schema": { "createIndex": { "range": [ { "alias": "category", "value": "string(document.metadata.category)", "sort": "ASC" } ], "partition": [ { "alias": "correlation_id", "value": "document.correlation_id" } ], "on": "Transaction", "constraints": { "hasCategory": "has(document.metadata.category)" }, "unique": false } } } } ``` ### createSearchIndex Create a search index for full text search support. Full text search indexes are powered by opensearch. These indexes are eventually consistent (populated by the async materializer after the source write commits), but have the ability to execute complex queries utilizing the opensearch indexing engine. An explicit `opensearchSchema` is required — it declares the Opensearch field types for the indexed documents and keeps sort/filter/cursor behavior stable. #### Resolves to [`Index!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``input`` - [`CreateSearchIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-search-index-input) * ### createView Create an view for a set of source tables. Views are materialized views that are defined by a CEL-expression map and get triggered by changes to one or more source tables. They allow for creating denormalized data structures that are automatically updated whenever source data changes. Each view has: - A document schema defined as a map of CEL expressions - Source table(s) that trigger updates to the view - Optional dimension(s) for partitioning and uniqueness constraints - Optional filters that determine when the view should be updated When source data changes, the view is automatically recalculated based on the provided CEL expressions. #### Resolves to [`View!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view) #### Arguments --- * ``input`` - [`CreateViewInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-view-input) * Input for creating a new view materialized view. ### deleteIndex Delete an existing index. When `on: View`, `viewName` must be supplied to identify the target view. #### Resolves to [`Index`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * Record types which support custom indexes. --- * ``viewName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. **Request** ```graphql mutation SchemaDeleteIndex { schema { deleteIndex(name: "Transaction.metadata.category", on: Transaction) { name on } } } ``` **Response** ```json { "data": { "schema": { "deleteIndex": { "name": "Transaction.metadata.category", "on": "Transaction" } } } } ``` ### deleteView Delete an existing view. #### Resolves to [`View`](https://www.twisp.com/docs/reference/graphql/types/object.md#view) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ### updateSearchIndex Update a search index #### Resolves to [`Index`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * Record types which support custom indexes. --- * ``opensearchSchema`` - [`OpensearchSchemaInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-input) * ## updateAccount Update fields on an existing account. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`AccountUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-update-input) * Fields to update. **Request** ```graphql mutation UpdateAccount($accountCardSettlementId: UUID!) { updateAccount(id: $accountCardSettlementId, input: { code: "CARD.SETTLE" }) { accountId code history(first: 2) { nodes { version code } } } } ``` **Response** ```json { "data": { "updateAccount": { "accountId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8", "code": "CARD.SETTLE", "history": { "nodes": [ { "version": 2, "code": "CARD.SETTLE" }, { "version": 1, "code": "SETTLE.CARD" } ] } } } } ``` **Variables** ```json { "accountCardSettlementId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8" } ``` ## updateAccountSet Update fields on an existing account set. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`AccountSet!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`AccountSetUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-update-input) * Fields to update. **Request** ```graphql mutation UpdateAccountSet($accountSetCustomersId: UUID!) { updateAccountSet( id: $accountSetCustomersId input: { name: "Customer Wallets", code: "CUSTOMERS.WALLETS" } ) { accountSetId name code history(first: 2) { nodes { version name code } } } } ``` **Response** ```json { "data": { "updateAccountSet": { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "name": "Customer Wallets", "code": "CUSTOMERS.WALLETS", "history": { "nodes": [ { "version": 3, "name": "Customer Wallets", "code": "CUSTOMERS.WALLETS" }, { "version": 2, "name": "Customers", "code": "Ke8_GJexQNmYUifxYHtsqIIstZ_OUUg3g5Eq87el_FE" } ] } } } } ``` **Variables** ```json { "accountSetCustomersId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8" } ``` ## updateCalculation Update fields on an existing calculation. #### Resolves to [`Calculation!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`CalculationUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#calculation-update-input) * Fields to update. **Request** ```graphql mutation UpdateCalculation { updateCalculation( id: "5867b5dd-fc69-416c-80f5-62e8a53610d5" input: { code: "EFFECTIVE_DATE_LOCAL" description: "Track balances per EFFECTIVE_DATE locally in an account." } ) { calculationId code description } } ``` **Response** ```json { "data": { "updateCalculation": { "calculationId": "5867b5dd-fc69-416c-80f5-62e8a53610d5", "code": "EFFECTIVE_DATE_LOCAL", "description": "Track balances per EFFECTIVE_DATE locally in an account." } } } ``` ## updateEntry Update an existing ledger entry. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Entry!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`EntryUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#entry-update-input) * Entry fields to update. ## updateJournal Update an existing journal. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Journal!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`JournalUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#journal-update-input) * Journal fields to update. **Request** ```graphql mutation UpdateJournal($journalGLId: UUID!) { updateJournal( id: $journalGLId input: { description: "_The_ ledger. The only one." } ) { journalId description history(first: 2) { nodes { version description } } } } ``` **Response** ```json { "data": { "updateJournal": { "journalId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "description": "_The_ ledger. The only one.", "history": { "nodes": [ { "version": 2, "description": "_The_ ledger. The only one." }, { "version": 1, "description": "General Ledger" } ] } } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ## updateTranCode Update an existing tran code. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`TranCode!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`TranCodeUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-update-input) * TranCode fields to update. **Request** ```graphql mutation UpdateTranCode($tcBookTransferId: UUID!) { updateTranCode( id: $tcBookTransferId input: { description: "Book transfer between two customer wallet accounts." vars: { hello: "string('world')" } 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 } vars history(first: 2) { nodes { version description vars } } } } ``` **Response** ```json { "data": { "updateTranCode": { "tranCodeId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855", "description": "Book transfer between two customer wallet accounts.", "entries": [ { "metadata": "{'first': 1}" }, { "metadata": "{'second':2}" } ], "vars": { "amount2": "decimal('1.00')", "amount3": "this.amount2", "hello": "string('world')" }, "history": { "nodes": [ { "version": 2, "description": "Book transfer between two customer wallet accounts.", "vars": { "amount2": "decimal('1.00')", "amount3": "this.amount2", "hello": "string('world')" } }, { "version": 1, "description": "Book transfer between two internal accounts.", "vars": { "amount2": "decimal('1.00')", "amount3": "this.amount2" } } ] } } } } ``` **Variables** ```json { "tcBookTransferId": "e0ffa94d-ca03-4ae2-aa69-cbaaa21d3855" } ``` ## updateTransaction Update an existing transaction. To ensure data integrity, only a subset of fields are allowed. #### Resolves to [`Transaction!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``input`` - [`TransactionUpdateInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-update-input) * Transaction fields to update. **Request** ```graphql mutation UpdateTransaction { updateTransaction( id: "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68" input: { metadata: { reconciled: true } } ) { transactionId metadata history(first: 2) { nodes { version metadata } } } } ``` **Response** ```json { "data": { "updateTransaction": { "transactionId": "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68", "metadata": { "reconciled": true }, "history": { "nodes": [ { "version": 2, "metadata": { "reconciled": true } }, { "version": 1, "metadata": {} } ] } } } } ``` ## updateVelocityControl #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``input`` - [`UpdateVelocityControlInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-velocity-control-input) * ## updateVelocityLimit #### Resolves to [`VelocityLimit`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) #### Arguments --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``input`` - [`UpdateVelocityLimitInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-velocity-limit-input) * ## voidTransaction Void an existing transaction. #### Resolves to [`Transaction`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. --- * ``properties`` - [`VoidTransactionPropertiesInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#void-transaction-properties-input) * **Request** ```graphql mutation VoidTransaction($transactionId: UUID!) { voidTransaction(id: $transactionId) { transactionId voidOf } } ``` **Response** ```json { "data": { "voidTransaction": { "transactionId": "61a31b31-51d3-54e1-8420-f2c0d953adc5", "voidOf": "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68" } } } ``` **Variables** ```json { "transactionId": "6b5e47b6-60d2-49bf-8210-0e4c3dd3ec68" } ``` ## warehouse Mutations in the `warehouse` namespace are used to manage the twisp data warehouse. ### batchExecuteStatement #### Resolves to [`BatchExecuteStatementOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#batch-execute-statement-output) #### Arguments --- * ``input`` - [`BatchExecuteStatementInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#batch-execute-statement-input) * ### cancelStatement #### Resolves to [`CancelStatementOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#cancel-statement-output) #### Arguments --- * ``input`` - [`CancelStatementInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#cancel-statement-input) * ### executeStatement #### Resolves to [`ExecuteStatementOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#execute-statement-output) #### Arguments --- * ``input`` - [`ExecuteStatementInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#execute-statement-input) * ### executeStatementSync #### Resolves to [`ExecuteStatementSyncOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#execute-statement-sync-output) #### Arguments --- * ``input`` - [`ExecuteStatementSyncInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#execute-statement-sync-input) * **Request** ```graphql 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 } } } } ``` **Response** ```json { "data": { "warehouse": { "executeStatementSync": { "records": [ { "fields": [ { "value": { "str": "6BEVvBrRTiGFH4MlyyzHTQ==" } }, { "value": { "str": "e81115bc1ad14e21851f8325cb2cc74d" } } ] } ], "columnMetadata": [ { "name": "accountid" }, { "name": "uuid" } ] } } } } ``` ### export #### Resolves to [`Export!`](https://www.twisp.com/docs/reference/graphql/types/object.md#export) #### Arguments --- * ``input`` - [`ExportInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#export-input) * ## workflow Mutations in the `workflow` namespace are used to manage and execute workflows. ### execute Execute a workflow identified by `workflowId`. #### Resolves to [`WorkflowExecution!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) #### Arguments --- * ``input`` - [`WorkflowInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#workflow-input) * Fields to execute a new workflow. ### executeTask Execution workflow identified by `workflowId` and `executionId` to the state identified by `task`. #### Resolves to [`WorkflowExecution!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) #### Arguments --- * ``input`` - [`WorkflowInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#workflow-input) * Fields to execute a new workflow. --- # Queries Queries retrieve data from the system by specifying the fields to be returned. ## account Get a single account by its `accountId`. #### Resolves to [`Account`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. _Example:_ ``"3ea12e45-7df2-4293-9434-feb792affc91"`` **Request** ```graphql query GetAccount { account(id: "a9c8dde6-c0e5-407c-9d99-029c523f7ea8") { accountId code name description normalBalanceType status } } ``` **Response** ```json { "data": { "account": { "accountId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8", "code": "SETTLE.CARD", "name": "Card Settlement", "description": "Settlement account for card transactions.", "normalBalanceType": "CREDIT", "status": "ACTIVE" } } } ``` ## accountSet Get a single account set by its `accountSetId`. #### Resolves to [`AccountSet`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql query GetAccountSet { accountSet(id: "29ef3f18-97b1-40d9-9852-27f1607b6ca8") { accountSetId name description members(first: 10) { nodes { ... on Account { accountId code name } } } } } ``` **Response** ```json { "data": { "accountSet": { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "name": "Customers", "description": "All customer wallets.", "members": { "nodes": [ { "accountId": "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b", "code": "CUST.Bobby", "name": "Bobby" }, { "accountId": "260fd651-8819-4f99-9c8a-87d27e03ee4c", "code": "CUST.Alicia", "name": "Alicia" } ] } } } } ``` ## accountSets Select one or more account sets. Specify the index to use and apply filters to your query. #### Resolves to [`AccountSetConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-connection) #### Arguments --- * ``index`` - [`AccountSetIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`AccountSetFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of sets to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve sets. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAccountSets { accountSets( index: { name: NAME } where: { name: { like: "" } journalId: { eq: "822cb59f-ce51-4837-8391-2af3b7a5fc51" } } first: 10 ) { nodes { accountSetId name description } } } ``` **Response** ```json { "data": { "accountSets": { "nodes": [ { "accountSetId": "29ef3f18-97b1-40d9-9852-27f1607b6ca8", "name": "Customers", "description": "All customer wallets." }, { "accountSetId": "0b195688-c1e6-4577-b5dd-0075c2feca35", "name": "Settlement", "description": "All settlement accounts." } ] } } } ``` ## accounts Select one or more accounts. Specify the index to use and apply filters to your query. #### Resolves to [`AccountConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-connection) #### Arguments --- * ``index`` - [`AccountIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`AccountFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAccounts { accounts( index: { name: CODE } where: { code: { like: "CUST." } } first: 2 ) { nodes { accountId code name description normalBalanceType status } } } ``` **Response** ```json { "data": { "accounts": { "nodes": [ { "accountId": "260fd651-8819-4f99-9c8a-87d27e03ee4c", "code": "CUST.Alicia", "name": "Alicia", "description": "Alicia's customer wallet.", "normalBalanceType": "DEBIT", "status": "ACTIVE" }, { "accountId": "ae9d36cb-dcf5-41a9-bc1e-99a1cf56ef5b", "code": "CUST.Bobby", "name": "Bobby", "description": "Bobby's customer wallet.", "normalBalanceType": "DEBIT", "status": "ACTIVE" } ] } } } ``` ## ach ### configuration Read an existing configuration for processing ACH files. #### Resolves to [`AchConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. _Example:_ ``"fe27128a-b331-4e0e-94f8-9a32443fee36"`` **Request** ```graphql query Configuration { ach { configuration(id: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff") { configId timeZone } } } ``` **Response** ```json { "data": { "ach": { "configuration": { "configId": "1dc71d60-f463-4bb6-b82a-ab42e2f923ff", "timeZone": "America/Los_Angeles" } } } } ``` ### configurations #### Resolves to [`AchConfigurationConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. **Request** ```graphql query Configurations { ach { configurations(first: 100) { nodes { configId timeZone } } } } ``` **Response** ```json { "data": { "ach": { "configurations": { "nodes": [ { "configId": "1dc71d60-f463-4bb6-b82a-ab42e2f923ff", "timeZone": "America/Los_Angeles" } ] } } } } ``` ### file Read the file info for status of file processing. #### Resolves to [`AchFileInfo`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info) #### Arguments --- * ``id`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier returned from processFile mutation. _Example:_ ``"549f0093-6476-4625-b38e-2109a0d5d3f8"`` --- * ``fileKey`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * File key of uploaded ACH file. _Example:_ ``"ppd-credits.ach"`` --- * ``configId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Configuration identifier used in processFile mutation. _Example:_ ``"987908ab-34d4-42f5-9213-c835f96545e1"`` ### files #### Resolves to [`AchFileInfoConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info-connection) #### Arguments --- * ``index`` - [`AchFileInfoIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-file-info-index-input) * --- * ``where`` - [`AchFileInfoFilterInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-file-info-filter-input) * --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## admin Queries in the `admin` namespace retrieve organization data like users, groups, and tenants. ### aliases Get the list of the organization's tenant aliases in the current region, ordered by `alias`. #### Resolves to [`AliasConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. ### groups Get the list of groups, ordered by `name`. #### Resolves to [`GroupConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#group-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAdminGroups { admin { groups(first: 5) { nodes { name description policy } } } } ``` **Response** ```json { "data": { "admin": { "groups": { "nodes": [ { "name": "Admin", "description": "Default Group", "policy": "[{\"actions\": [\"*\"],\"effect\": \"ALLOW\",\"resources\":[\"*\"]}]" }, { "name": "deny-policy-1", "description": "a group with a deny policy", "policy": "[{\"actions\": [\"*\"],\"effect\": \"DENY\",\"resources\":[\"*\"]}]" }, { "name": "read-only-policy-1", "description": "a group with a read-only policy", "policy": "[{\"actions\": [\"db:Select\"],\"effect\": \"ALLOW\",\"resources\":[\"*\"]}]" } ] } } } } ``` ### organization Get the current organization. #### Resolves to [`Organization!`](https://www.twisp.com/docs/reference/graphql/types/object.md#organization) #### Arguments **Request** ```graphql query GetAdminOrganization { admin { organization { id name description } } } ``` **Response** ```json { "data": { "admin": { "organization": { "id": "932343ab-33ee-410d-9663-7ddaec4d5bfa", "name": "test_org", "description": "this is a test organization" } } } } ``` ### restoreStatus Retrieves the status of a restoration. #### Resolves to [`RestoreStatus`](https://www.twisp.com/docs/reference/graphql/types/object.md#restore-status) #### Arguments --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ### tenants Get the list of tenants, ordered by `accountId`. #### Resolves to [`TenantConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAdminTenants { admin { tenants(first: 5) { nodes { name organizationId description } } } } ``` **Response** ```json { "data": { "admin": { "tenants": { "nodes": [ { "name": "PreProduction", "organizationId": "932343ab-33ee-410d-9663-7ddaec4d5bfa", "description": "tenant for preprod integrations" }, { "name": "TestTenant", "organizationId": "932343ab-33ee-410d-9663-7ddaec4d5bfa", "description": "this is a test tenant" } ] } } } } ``` ### usage Retrieves the read and write usage units on per day basis. The metrics returned are on the half open interval. returns metris `period >= 2025-06-01T00:00:00.000Z && period < 2025-07-01T00:00:00.000Z` #### Resolves to [`Usage`](https://www.twisp.com/docs/reference/graphql/types/object.md#usage) #### Arguments --- * ``input`` - [`UsageInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#usage-input) * ### users Get the list of human users, ordered by `email`. #### Resolves to [`UserConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#user-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAdminUsers { admin { users(first: 5) { nodes { email organizationId groupIds } } } } ``` **Response** ```json { "data": { "admin": { "users": { "nodes": [ { "email": "test@twisp.com", "organizationId": "932343ab-33ee-410d-9663-7ddaec4d5bfa", "groupIds": ["4dcef8d5-186b-4db1-aa00-8d5b2eee85f8"] } ] } } } } ``` ## attachedControls List all velocity controls attached the specified Account or Account Set. #### Resolves to [`ResolvedVelocityControlConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control-connection) #### Arguments --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account or Account Set Id to look up attached controls --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``after`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. _Default:_ ``""`` ## auth Queries in the `auth` namespace are used to retrieve clients and their policies. Use the `client` query to retrieve a single client, and `clients` to retrieve a list of clients. ### client Get a single client by the `principal`. #### Resolves to [`Client`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) #### Arguments --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Principal of the client. **Request** ```graphql query GetAuthClient($authClientGithub: String!) { auth { client(principal: $authClientGithub) { principal name policies { effect actions resources } } } } ``` **Response** ```json { "data": { "auth": { "client": { "principal": "arn:aws:iam::048962233173:user/github.action", "name": "Github", "policies": [ { "effect": "ALLOW", "actions": ["SELECT", "INSERT", "UPDATE", "DELETE"], "resources": ["financial.*"] } ] } } } } ``` **Variables** ```json { "authClientGithub": "arn:aws:iam::048962233173:user/github.action" } ``` ### clients Lists all clients. #### Resolves to [`ClientConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#client-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetAuthClients { auth { clients(first: 10) { nodes { principal name } } } } ``` **Response** ```json { "data": { "auth": { "clients": { "nodes": [ { "principal": "arn:aws:iam::048962233173:user/feed.action", "name": "Read Stream" }, { "principal": "arn:aws:iam::048962233173:user/github.action", "name": "Github" } ] } } } } ``` ## balance Get a balance for an account. #### Resolves to [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) #### Arguments --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the journal for the balance. If omitted, the default journal will be used. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the account for the balance. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * Currency of the balance. _Default:_ ``"USD"`` --- * ``calculationId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * If provided, look up based on calculation id and dimensions for calculation. --- * ``dimension`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * If provided, look up based on calculation id and dimensions for calculation. The values in this should be string representation of values. --- * ``effective`` - [`Effective`](https://www.twisp.com/docs/reference/graphql/types/input.md#effective) * If enabled and provided, look up balances based on effective date. --- * ``materialize`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * If concurrent enabled, compute balance with all visible transactions. --- * ``type`` - [`BalanceType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#balance-type) * If concurrent enabled, the isolation level of the balance returned. **Request** ```graphql query GetBalance($journalGLId: UUID!, $accountCardSettlementId: UUID!) { balance( accountId: $accountCardSettlementId journalId: $journalGLId currency: "USD" ) { available(layer: SETTLED) { drBalance { units } crBalance { units } normalBalance { formatted(as: { locale: "en-US" }) } } entries(first: 10) { nodes { entryType amount { units currency } direction layer } } } } ``` **Response** ```json { "data": { "balance": { "available": { "drBalance": { "units": "4.53" }, "crBalance": { "units": "0" }, "normalBalance": { "formatted": "-$4.53" } }, "entries": { "nodes": [ { "entryType": "CARD_HOLD_CLEAR_CR", "amount": { "units": "4.53", "currency": "USD" }, "direction": "CREDIT", "layer": "PENDING" }, { "entryType": "CARD_SETTLEMENT_DR", "amount": { "units": "4.53", "currency": "USD" }, "direction": "DEBIT", "layer": "SETTLED" }, { "entryType": "CARD_HOLD_DR", "amount": { "units": "4.53", "currency": "USD" }, "direction": "DEBIT", "layer": "PENDING" } ] } } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "accountCardSettlementId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8" } ``` ## balances Select one or more balances. Specify the index to use and apply filters to your query. #### Resolves to [`BalanceConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-connection) #### Arguments --- * ``index`` - [`BalanceIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#balance-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`BalanceFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#balance-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetBalances($journalGLId: String!, $accountCustomerAliciaId: String!) { balances( index: { name: ACCOUNT_ID } where: { accountId: { eq: $accountCustomerAliciaId } journalId: { eq: $journalGLId } } first: 20 ) { nodes { entry { entryType } currency settled { normalBalance { formatted(as: { locale: "en-US" }) } } version } } } ``` **Response** ```json { "data": { "balances": { "nodes": [ { "entry": { "entryType": "FX_BUY_CR" }, "currency": "EUR", "settled": { "normalBalance": { "formatted": "€2.0145" } }, "version": 1 }, { "entry": { "entryType": "FX_SELL_DR" }, "currency": "USD", "settled": { "normalBalance": { "formatted": "$1.63" } }, "version": 6 } ] } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "accountCustomerAliciaId": "260fd651-8819-4f99-9c8a-87d27e03ee4c" } ``` ## bulk ### execution Retrieve single bulk query execution by it's `executionId`. #### Resolves to [`BulkQueryExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ### executions List bulk query executions. #### Resolves to [`BulkQueryExecutionConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution-connection) #### Arguments --- * ``index`` - [`BulkQueryExecutionIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#bulk-query-execution-index-input) * Select the index to use. --- * ``where`` - [`BulkQueryExecutionFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#bulk-query-execution-filter-input) * Filter conditions. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor for pagination. ## calculation Retrieve a calculation by its identifier. #### Resolves to [`Calculation`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) #### Arguments --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. **Request** ```graphql query ReadCalculation { calculation(calculationId: "5867b5dd-fc69-416c-80f5-62e8a53610d5") { calculationId code description dimensions { alias value } } } ``` **Response** ```json { "data": { "calculation": { "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" } ] } } } ``` ## calculations Retrieve calculations by index. #### Resolves to [`CalculationConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation-connection) #### Arguments --- * ``index`` - [`CalculationIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#calculation-index-input) * --- * ``where`` - [`CalculationFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#calculation-filter-input) * --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. **Request** ```graphql query ListActiveGlobalCalculations { calculations( index: { name: GLOBAL } where: { status: { eq: "ACTIVE" } } first: 1 ) { nodes { calculationId code description dimensions { alias value } } } } ``` **Response** ```json { "data": { "calculations": { "nodes": [ { "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" } ] } ] } } } ``` ## entries Select one or more entries. Specify the index to use and apply filters to your query. #### Resolves to [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) #### Arguments --- * ``index`` - [`EntryIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#entry-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`EntryFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#entry-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Return the first n-edges of a search. Use `after` to paginate forward. --- * ``last`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Return previous n-edges of a search relative to the `before` cursor. **NOTE:** only available on search indexes. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor to paginate forward through a search result. When no cursor is provided, the query uses the default starting cursor. --- * ``before`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor to paginate backwards through a search result. **NOTE:** Only available on search indexes. **Request** ```graphql query GetEntries { entries( index: { name: TRANSACTION_ID } where: { transactionId: { eq: "114a8b1e-d00b-4e13-ab27-ec3472622c0a" } } first: 10 ) { nodes { entryType account { name } direction amount { units currency } } } } ``` **Response** ```json { "data": { "entries": { "nodes": [ { "entryType": "CARD_HOLD_CR", "account": { "name": "Alicia" }, "direction": "CREDIT", "amount": { "units": "4.53", "currency": "USD" } }, { "entryType": "CARD_HOLD_DR", "account": { "name": "Card Settlement" }, "direction": "DEBIT", "amount": { "units": "4.53", "currency": "USD" } } ] } } } ``` ## entry Get a single entry by its `entryId`. #### Resolves to [`Entry`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. ## events Mutations in the `events` namespace are used to manage event subscriptions, such as webhooks. ### endpoint Get a single endpoint by it's `endpointId` #### Resolves to [`Endpoint`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. **Request** ```graphql query GetEndpoint { events { endpoint(id: "345940ed-2726-4b20-88aa-820857ac0e68") { endpointId status endpointType url subscription description } } } ``` **Response** ```json { "data": { "events": { "endpoint": { "endpointId": "345940ed-2726-4b20-88aa-820857ac0e68", "status": "ENABLED", "endpointType": "WEBHOOK", "url": "https://webhook.site/twisp-webhook-test", "subscription": ["balance*", "account.*"], "description": "subscribe to balance and account events" } } } } ``` ### endpoints Select one or more endpoints. Specify the index to use and apply filters to your query. #### Resolves to [`EndpointConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint-connection) #### Arguments --- * ``index`` - [`EndpointIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#endpoint-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`EndpointFilterInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#endpoint-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. ## files ### list #### Resolves to [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) #### Arguments --- * ``keyPrefix`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ### listPage #### Resolves to [`FileListPage!`](https://www.twisp.com/docs/reference/graphql/types/object.md#file-list-page) #### Arguments --- * ``keyPrefix`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``pageSize`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. _Default:_ ``100`` --- * ``pageToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## iso8583 ### config Read an existing ISO8583 configuration. #### Resolves to [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) #### Arguments --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. _Example:_ ``"670504f6-0515-11f0-a441-069b540ea27c"`` **Request** ```graphql query GetISO8583Config { iso8583 { config(configId: "670504f6-0515-11f0-a441-069b540ea27c") { id configId journalId settlementAccountId timeZone description processor version } } } ``` **Response** ```json { "data": { "iso8583": { "config": { "id": "iso8583:config:670504f6-0515-11f0-a441-069b540ea27c", "configId": "670504f6-0515-11f0-a441-069b540ea27c", "journalId": "8b65c8dc-0515-11f0-a441-069b540ea27c", "settlementAccountId": "779886bc-0515-11f0-aa78-069b540ea27c", "timeZone": "America/Chicago", "description": "ISO8583 Test Config 1", "processor": "I2C", "version": 1 } } } } ``` ### configs List all ISO8583 configurations. #### Resolves to [`ISO8583ConfigConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * Sort order for results. **Request** ```graphql query ListISO8583Configs { iso8583 { configs(first: 10) { pageInfo { hasNextPage hasPreviousPage } edges { node { configId journalId settlementAccountId timeZone description processor } } } } } ``` **Response** ```json { "data": { "iso8583": { "configs": { "pageInfo": { "hasNextPage": false, "hasPreviousPage": false }, "edges": [ { "node": { "configId": "670504f6-0515-11f0-a441-069b540ea27c", "journalId": "8b65c8dc-0515-11f0-a441-069b540ea27c", "settlementAccountId": "779886bc-0515-11f0-aa78-069b540ea27c", "timeZone": "America/Chicago", "description": "ISO8583 Test Config 1", "processor": "I2C" } }, { "node": { "configId": "7e0d3fa2-0515-11f0-a6b2-069b540ea27c", "journalId": "8b65c8dc-0515-11f0-a441-069b540ea27c", "settlementAccountId": "779886bc-0515-11f0-aa78-069b540ea27c", "timeZone": "America/New_York", "description": "ISO8583 Test Config 2", "processor": "I2C" } } ] } } } } ``` ## journal Get a single journal by its `journalId`. If `journalId` is omitted, return the default journal. #### Resolves to [`Journal`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) #### Arguments --- * ``id`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql query GetJournal($journalGLId: UUID!) { journal(id: $journalGLId) { name description status version } } ``` **Response** ```json { "data": { "journal": { "name": "GL", "description": "General Ledger", "status": "ACTIVE", "version": 1 } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ## journals Select one or more journals. Specify the index to use and apply filters to your query. #### Resolves to [`JournalConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection) #### Arguments --- * ``index`` - [`JournalIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#journal-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`JournalFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#journal-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetJournals { journals( index: { name: STATUS } where: { status: { eq: "ACTIVE" } } first: 10 ) { nodes { journalId name description status } } } ``` **Response** ```json { "data": { "journals": { "nodes": [ { "journalId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "name": "GL", "description": "General Ledger", "status": "ACTIVE" }, { "journalId": "432d2b1b-c647-4b0a-aa78-0945241f8e6d", "name": "SL", "description": "Securities Ledger", "status": "ACTIVE" } ] } } } ``` ## kv Read a single key/value record by its natural key. Limits: - `namespace`: max 512 UTF-8 bytes - `key`: max 512 UTF-8 bytes #### Resolves to [`KVValue`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) #### Arguments --- * ``namespace`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## kvs List key/value records through either the built-in namespace index or a custom index. Notes: - `index: { name: Namespace }` requires `where.namespace.eq` - `index: { name: Custom }` requires `where.custom.index` plus the custom index partition filter(s) #### Resolves to [`KVConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvconnection) #### Arguments --- * ``index`` - [`KVIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#kvindex-input) * --- * ``where`` - [`KVFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#kvfilter-input) * --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## node #### Resolves to [`Node`](https://www.twisp.com/docs/reference/graphql/types/interface.md#node) #### Arguments --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. ## schema Queries in the `schema` namespace are used to retrieve information about custom indexes, aggregates, and historical indexes. ### index Get a single index by `name`. #### Resolves to [`Index`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``on`` - [`IndexOnEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * The type of record this index applies to. --- * ``viewName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the target view. Required when `on: View`; ignored otherwise. **Request** ```graphql query GetSchemaIndex($indexName: String!) { schema { index(name: $indexName, on: Account) { name on unique range { alias value sort } partition { alias value } constraints } } } ``` **Response** ```json { "data": { "schema": { "index": { "name": "Account.metadata.type", "on": "Account", "unique": false, "range": [ { "alias": "type", "value": "string(document.metadata.type)", "sort": "ASC" } ], "partition": [ { "alias": "type", "value": "string(document.metadata.type)" } ], "constraints": { "hasCategory": "has(document.metadata.type)" } } } } } ``` **Variables** ```json { "indexName": "Account.metadata.type" } ``` ### indexes List all indexes, ordered by `name`. #### Resolves to [`IndexConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetSchemaIndexes { schema { indexes(first: 10) { nodes { name range { alias value sort } partition { alias value } on constraints unique } } } } ``` **Response** ```json { "data": { "schema": { "indexes": { "nodes": [ { "name": "Account.metadata.type", "range": [ { "alias": "type", "value": "string(document.metadata.type)", "sort": "ASC" } ], "partition": [ { "alias": "type", "value": "string(document.metadata.type)" } ], "on": "Account", "constraints": { "hasCategory": "has(document.metadata.type)" }, "unique": false }, { "name": "AccountSet.metadata.type", "range": [ { "alias": "type", "value": "string(document.metadata.type)", "sort": "ASC" } ], "partition": [ { "alias": "type", "value": "string(document.metadata.type)" } ], "on": "AccountSet", "constraints": { "hasCategory": "has(document.metadata.type)" }, "unique": false }, { "name": "Transaction.metadata.category", "range": [ { "alias": "category", "value": "string(document.metadata.category)", "sort": "ASC" } ], "partition": [ { "alias": "category", "value": "string(document.metadata.category)" } ], "on": "Transaction", "constraints": { "hasCategory": "has(document.metadata.category)" }, "unique": false } ] } } } } ``` ### view Get a single view by `name`. #### Resolves to [`View`](https://www.twisp.com/docs/reference/graphql/types/object.md#view) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this view. Typically human readable. ### views List all views, ordered by `name`. #### Resolves to [`ViewConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-connection) #### Arguments --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. ## tranCode Get a single tran code by its `tranCodeId`. #### Resolves to [`TranCode`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql query GetTranCode($tcCardHoldId: UUID!) { tranCode(id: $tcCardHoldId) { code description params { name type description } transaction { journalId effective correlationId description } entries { accountId layer direction units currency } status metadata } } ``` **Response** ```json { "data": { "tranCode": { "code": "CARD_HOLD", "description": "Place an authorization hold on an account for the amount specified.", "params": [ { "name": "account", "type": "UUID", "description": "The account to place the hold on." }, { "name": "amount", "type": "DECIMAL", "description": "The amount of the hold." }, { "name": "currency", "type": "STRING", "description": "Currency used for transaction." }, { "name": "isDebit", "type": "BOOLEAN", "description": "If true (default), debit the account specified. If false, credit the account." }, { "name": "correlation", "type": "STRING", "description": "Correlation identifier to group transactions following on from this hold." }, { "name": "effective", "type": "DATE", "description": "Effective date of the transaction." } ], "transaction": { "journalId": "uuid('822cb59f-ce51-4837-8391-2af3b7a5fc51')", "effective": "params.effective", "correlationId": "params.correlation", "description": "'Card authorization hold placed for ' + string(params.amount) + ' ' + params.currency" }, "entries": [ { "accountId": "params.account", "layer": "PENDING", "direction": "params.isDebit ? DEBIT : CREDIT", "units": "params.amount", "currency": "params.currency" }, { "accountId": "uuid('a9c8dde6-c0e5-407c-9d99-029c523f7ea8')", "layer": "PENDING", "direction": "params.isDebit ? CREDIT : DEBIT", "units": "params.amount", "currency": "params.currency" } ], "status": "ACTIVE", "metadata": { "category": "Card" } } } } ``` **Variables** ```json { "tcCardHoldId": "8f67fb0b-795a-47b3-9b03-40351e8ac584" } ``` ## tranCodes Select one or more tran codes. Specify the index to use and apply filters to your query. #### Resolves to [`TranCodeConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-connection) #### Arguments --- * ``index`` - [`TranCodeIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`TranCodeFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetTranCodes { tranCodes( index: { name: STATUS } where: { status: { eq: "ACTIVE" } } first: 10 ) { nodes { code metadata } } } ``` **Response** ```json { "data": { "tranCodes": { "nodes": [ { "code": "ACH_CREDIT", "metadata": { "category": "ACH" } }, { "code": "ACH_DEBIT", "metadata": { "category": "ACH" } }, { "code": "BOOK_TRANSFER", "metadata": { "category": "Internal" } }, { "code": "CARD_HOLD", "metadata": { "category": "Card" } }, { "code": "CARD_HOLD_CANCEL", "metadata": { "category": "Card" } }, { "code": "CARD_HOLD_EXPIRE", "metadata": { "category": "Card" } }, { "code": "CARD_HOLD_MODIFICATION", "metadata": { "category": "Card" } }, { "code": "CARD_TX_CLEARING", "metadata": { "category": "Card" } }, { "code": "EXCHANGE_CURRENCY", "metadata": { "category": "FX" } } ] } } } ``` ## transaction Get a single transaction by its `transactionId`. #### Resolves to [`Transaction`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier. **Request** ```graphql query GetTransaction { transaction(id: "434696a7-56e5-4e14-a97a-884820690a22") { description effective tranCode { code } journal { name } metadata entries(first: 10) { nodes { sequence entryType layer direction account { name } amount { formatted(as: { locale: "en-US" }) } } } } } ``` **Response** ```json { "data": { "transaction": { "description": "Exchange 2.37 USD for EUR at a 1:0.85 exchange rate.", "effective": "2022-09-11", "tranCode": { "code": "EXCHANGE_CURRENCY" }, "journal": { "name": "GL" }, "metadata": { "buy": "EUR", "rate": "0.85", "sell": "USD" }, "entries": { "nodes": [ { "sequence": 0, "entryType": "FX_SELL_DR", "layer": "SETTLED", "direction": "CREDIT", "account": { "name": "Alicia" }, "amount": { "formatted": "$2.37" } }, { "sequence": 1, "entryType": "FX_SELL_CR", "layer": "SETTLED", "direction": "DEBIT", "account": { "name": "Foreign Exchange Broker" }, "amount": { "formatted": "$2.37" } }, { "sequence": 2, "entryType": "FX_BUY_DR", "layer": "SETTLED", "direction": "CREDIT", "account": { "name": "Foreign Exchange Broker" }, "amount": { "formatted": "€2.0145" } }, { "sequence": 3, "entryType": "FX_BUY_CR", "layer": "SETTLED", "direction": "DEBIT", "account": { "name": "Alicia" }, "amount": { "formatted": "€2.0145" } } ] } } } } ``` ## transactions Select one or more transactions. Specify the index to use and apply filters to your query. #### Resolves to [`TransactionConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-connection) #### Arguments --- * ``index`` - [`TransactionIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-index-input) * Select from a list of pre-defined indexes. For optimal performance, choose specific indexes on unique fields over more general ones. --- * ``where`` - [`TransactionFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-filter-input) * Filter the query according to specified conditions. Depending on the index chosen, different filters will be allowed. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. **Request** ```graphql query GetTransactions($journalGLId: String!) { transactions( index: { name: CORRELATION_ID } where: { correlationId: { eq: "4f2ac9a7-5e83-458b-a194-c8ac8d8fdcd5" } journalId: { eq: $journalGLId } } first: 10 ) { nodes { transactionId description effective tranCode { code } } } } ``` **Response** ```json { "data": { "transactions": { "nodes": [ { "transactionId": "114a8b1e-d00b-4e13-ab27-ec3472622c0a", "description": "Card authorization hold placed for 4.53 USD", "effective": "2022-09-10", "tranCode": { "code": "CARD_HOLD" } }, { "transactionId": "d94033a4-f438-4fcc-9c3b-c7adf3fd7b76", "description": "Card TX for 4.53 USD settled.", "effective": "2022-09-12", "tranCode": { "code": "CARD_TX_CLEARING" } } ] } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51" } ``` ## velocity Search for the velocity balance for an Account or Account Set. #### Resolves to [`[VelocityBalance]`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-balance) #### Arguments --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account or Account Set to search for velocity. --- * ``window`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The window of the balance to look up. If `velocityLimitId` not provided, will look up all velocity limits that support the defined window. _Example:_ ``{year: "2022", month:"9"}`` --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * The currency for the velocity to look up. _Default:_ ``"USD"`` --- * ``velocityLimitId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * If provided, retrieve this specific velocity limit. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * If provided, retrieve from specified journal. Otherwise will use default. ## velocityControl #### Resolves to [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## velocityControls #### Resolves to [`VelocityControlConnection`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control-connection) #### Arguments --- * ``index`` - [`VelocityControlIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-control-index-input) * --- * ``where`` - [`VelocityControlFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-control-filter-input) * --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. _Default:_ ``100`` --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## velocityLimit #### Resolves to [`VelocityLimit`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) #### Arguments --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## velocityLimits #### Resolves to [`VelocityLimitConnection`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit-connection) #### Arguments --- * ``index`` - [`VelocityLimitIndexInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-limit-index-input) * --- * ``where`` - [`VelocityLimitFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-limit-filter-input) * --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. _Default:_ ``100`` --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## view Get entries from a specific view by name. #### Resolves to [`ViewRecordConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-record-connection) #### Arguments --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the view to query. --- * ``where`` - [`ViewFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-filter) * Filters to apply based on the view's dimensions. --- * ``first`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of nodes to return on the connection. --- * ``after`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor indicating the start point to retrieve nodes. When no cursor is provided, the query uses the default starting cursor. ## warehouse Queries in the `warehouse` namespace are used to perform reads against the twisp data warehouse ### describeStatement #### Resolves to [`DescribeStatementOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#describe-statement-output) #### Arguments --- * ``input`` - [`DescribeStatementInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#describe-statement-input) * ### describeTable #### Resolves to [`DescribeTableOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#describe-table-output) #### Arguments --- * ``input`` - [`DescribeTableInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#describe-table-input) * ### export #### Resolves to [`Export`](https://www.twisp.com/docs/reference/graphql/types/object.md#export) #### Arguments --- * ``id`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ### getStatementResult #### Resolves to [`GetStatementResultOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#get-statement-result-output) #### Arguments --- * ``input`` - [`GetStatementResultInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#get-statement-result-input) * ### listDatabases #### Resolves to [`ListDatabasesOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-databases-output) #### Arguments --- * ``input`` - [`ListDatabasesInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#list-databases-input) * ### listSchemas #### Resolves to [`ListSchemasOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-schemas-output) #### Arguments --- * ``input`` - [`ListSchemasInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#list-schemas-input) * ### listStatements #### Resolves to [`ListStatementsOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-statements-output) #### Arguments --- * ``input`` - [`ListStatementsInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#list-statements-input) * ### listTables #### Resolves to [`ListTablesOutput`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-tables-output) #### Arguments --- * ``input`` - [`ListTablesInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#list-tables-input) * **Request** ```graphql query listTables { warehouse { listTables( input: { maxResults: 5, database: "twisp", schemaPattern: "public" } ) { tables { name } } } } ``` **Response** ```json { "data": { "warehouse": { "listTables": { "tables": [ { "name": "account_history" }, { "name": "accountcontext_history" }, { "name": "accountset_history" }, { "name": "accountsetmember_history" }, { "name": "backfilljob_history" } ] } } } } ``` **Variables** ```json {} ``` ## workflow ### execution Return the execution by execution id. #### Resolves to [`WorkflowExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) #### Arguments --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- # Enum Types Enum types define a set of predefined values that a field can take. ## AccountIndex Indexes for querying Accounts. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``ACCOUNT_ID`` * Index by `accountId` field. Must supply an `accountId: { eq: }` filter to the `where` object. --- * ``NAME`` * Eventually consistent index by `name` field. Use to apply query filters on the value of `name`. --- * ``CODE`` * Eventually consistent index by `code` field. When an `eq` filter is supplied, a strongly consistent index is used. Use to apply query filters on the value of `code`. --- * ``STATUS`` * Eventually consistent index by `status` field. Use to apply query filters on the value of `status`. --- * ``EXTERNAL_ID`` * Index by `externalId` field. Must supply an `externalId: { eq: }` filter to the `where` object. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. --- * ``CODE_UNIQUE`` * Index by `code` field. Must supply an `codeUnique: { eq: }` filter to the `where` object. ## AccountSetIndex Indexes for querying AccountSets. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``ACCOUNT_SET_ID`` * Index by `accountSetId` field. Must supply an `accountSetId: { eq: }` filter to the `where` object. --- * ``NAME`` * Eventually consistent index by `name` field. Use to apply query filters on the value of `name`. --- * ``CODE`` * Eventually consistent index by `code` field. When an `eq` filter is supplied, a strongly consistent index is used. Use to apply query filters on the value of `code`. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. ## AccountSetMemberType Account set members can be of type Account or AccountSet. #### Values --- * ``ACCOUNT`` * --- * ``ACCOUNT_SET`` * ## AccountSetMembershipState The lifecycle state of an in-flight account set membership change. #### Values --- * ``SETTLING`` * The member's balances are seeded into the set but the settle window is still open. --- * ``COMPLETE`` * The settle delta has been applied; the record lingers only until garbage collection. --- * ``REMOVING`` * A remove is in its suppression window: the member's balances have been reversed out of the set. --- * ``CANCELLED`` * The add was cancelled (e.g. removed inside its own window) and its seed reversed. ## AccountSetStatus Lifecycle status of an account set. #### Values --- * ``ACTIVE`` * The account set is active. --- * ``DELETED`` * The account set has been soft-deleted (mark-only; the row and balances persist; no un-delete). ## AccountStatus Account status determines whether the account is in active use or closed (locked). By default, all accounts are `ACTIVE`. When account is `LOCKED`, it cannot be changed and any attempt to write a ledger entry to this account will raise an error. #### Values --- * ``ACTIVE`` * ACTIVE = Account is open for posting. --- * ``LOCKED`` * LOCKED = Account is locked and will block posting. --- * ``INACTIVE`` * INACTIVE = Account is open for posting but will be LOCKED soon. ## AchConfigurationDirection The direction of ACH files a configuration processes. #### Values --- * ``BOTH`` * Configuration processes both RDFI and ODFI files. --- * ``RDFI`` * Configuration processes RDFI files only. --- * ``ODFI`` * Configuration processes ODFI files only. ## AchFileInfoIndex #### Values --- * ``PROCESSING_STATUS`` * Index by `processingStatus` field. Must supply both `processingStatus:{eq: }` and `configId:{eq: }` to the `where` object. ## AchFileProcessingStatus #### Values --- * ``UNKNOWN`` * File Processing state is unknown. --- * ``NEW`` * Newly created file processing state. --- * ``VALIDATING`` * File is being validated. --- * ``PARTITIONING`` * File is being partitioned for processing. --- * ``UPLOADED`` * File has been uploaded and will begin processing shortly. --- * ``PROCESSING`` * File is being processed and create webhooks are being actively sent for this file. --- * ``PROCESSED`` * All create webhooks have been sent for this file and entries are awaiting settlement. --- * ``ERROR`` * The system encountered an unrecoverable error while processing the file. See `processingDetail` for more information. --- * ``INVALID`` * The uploaded file failed validation. See `processingDetail` for more information. --- * ``ABORTED`` * The processing of this file was aborted. See `processingDetail` for more information. --- * ``COMPLETED`` * All entries from this file process have been either settled or queued for a return file. --- * ``PENDING`` * All entries have been posted to the configured pending account and await manual settlement or return. ## AchFileType #### Values --- * ``RDFI`` * --- * ``RDFI_RETURN`` * --- * ``RDFI_NOC`` * --- * ``ODFI`` * --- * ``ODFI_PULL_ONLY`` * --- * ``ODFI_PUSH_ONLY`` * --- * ``ODFI_RETURN`` * --- * ``ODFI_PREPROCESS_RETURN`` * --- * ``ODFI_PROCESSED`` * ## AchOffsetAccountType #### Values --- * ``CHECKING`` * --- * ``SAVINGS`` * ## BalanceIndex Indexes for querying Balances. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``ACCOUNT_ID`` * Index by `accountId` field. Must supply an `accountId: { eq: }` filter to the `where` object. --- * ``CALCULATION`` * Index by `calculationId` and `dimension` fields in addition to account. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. ## BalanceLimitType #### Values --- * ``AVAILABLE`` * Limit based on available balance at a particular layer. ## BalanceType All operations in Twisp are **strongly consistent** and transactionally isolated. Both concurrent and non-concurrent enabled accounts provide the same strong consistency guarantee on balances, but concurrent enabled accounts can adjust their balance isolation levels and latency characteristics according to different user needs. #### Values --- * ``FINAL`` * Return the latest calculated balance record for the account. This balance may be slightly stale but offers the lowest latency. --- * ``PREPARED`` * Return the latest calculated balance record plus any committed, but not yet FINAL, entries. This balance is transactionally consistent for the current snapshot and guaranteed to eventually match a FINAL balance record. --- * ``PROVISIONAL`` * Return the latest calculated balance record plus any committed, but not yet FINAL, entries along with all in-flight uncommitted entries. This balance is provisional since uncommitted entries are not guaranteed to commit. ## BranchIncludeEnum Classes of configuration entity that `branch` can copy into the new tenant. #### Values --- * ``Calculation`` * --- * ``CustomIndex`` * --- * ``Endpoint`` * --- * ``Journal`` * --- * ``TranCode`` * --- * ``VelocityControl`` * --- * ``View`` * ## BulkQueryExecutionIndex Indexes for querying bulk executions. #### Values --- * ``STATUS`` * Eventually consistent index by `status` field, sorted by `created` timestamp. ## BulkQueryExecutionStatus #### Values --- * ``CREATED`` * Execution is created but not yet started. --- * ``IN_PROGRESS`` * Execution is in progress. --- * ``SUMMARIZING`` * Execution is complete and results are being summarized. --- * ``COMPLETE`` * Execution is complete and results are available to download. --- * ``ERROR`` * There was an error that prevented execution. --- * ``CANCELLED`` * Execution was cancelled by the user. ## CalculationBackfillStatus #### Values --- * ``COMPLETE`` * Calculation is completely backfilled or was created before backfill support. --- * ``IN_PROGRESS`` * Backfill is in progress. --- * ``ERROR`` * There was an error in the backfill. --- * ``DETACHED`` * The calculation was detached. ## CalculationIndex #### Values --- * ``CALCULATION_ID`` * Index by `calculationId` field. Must supply `calculationId: { eq: }` filter to the `where` object. --- * ``CODE`` * Index by `code` field. Must supply `code: { eq: }` filter to the `where` object. --- * ``GLOBAL`` * Global calculations by `status` field. Must supply `status: { eq: }` filter to the `where` object. --- * ``LOCAL`` * Local calculations by `status` field. Must supply `status: { eq: }` filter to the `where` object. ## CalculationScope #### Values --- * ``GLOBAL`` * The calculation is computed on all accounts and sets in the journal. --- * ``LOCAL`` * The calculation is computed only on accounts and sets where it is attached. ## CalculationStatus #### Values --- * ``ACTIVE`` * Calculation is actively in use. --- * ``LOCKED`` * Calculation has been deleted and no longer in use. ## CelType #### Values --- * ``JSON`` * A json object --- * ``Timestamp`` * RFC-3339 formatted timestamp. --- * ``Duration`` * Golang formatted duration string. --- * ``Double`` * Signed 64 bit floating point. --- * ``Decimal`` * 128-Bit fixed precision decimal. --- * ``String`` * UTF-8 encoded string. --- * ``Bool`` * Boolean --- * ``Int`` * Signed 64-bit integer --- * ``UInt`` * Unsigned 64-bit integer --- * ``Bytes`` * Base64 encoded bytestring. --- * ``UUID`` * UUID supporting v1-8 ## CurrencyDisplay Defines how to render the currency indicator. #### Values --- * ``SYMBOL`` * Show the symbol for the currency. @example('$1.23') @example('€1.23') --- * ``CODE`` * Show the currency code. @example('USD') @example('EUR') --- * ``NONE`` * Don't show the code or symbol for the currency. ## DebitOrCredit Debit or credit? Sometimes these are abbreviated to DR and CR. #### Values --- * ``DEBIT`` * --- * ``CREDIT`` * ## EffectiveGranularity #### Values --- * ``YEAR`` * Year-level effective calculation (YYYY) --- * ``MONTH`` * Month-level effective calculation (YYYY_MM) --- * ``DAY`` * Day-level effective calculation (YYYY_MM_DD) ## EndpointIndex #### Values --- * ``ENDPOINT_ID`` * Index by `endpointId` field. Must supply an `endpointId: { eq: }` filter to the `where` object. --- * ``STATUS`` * Index by `status` field. Must supply an `status: { eq: }` filter to the `where` object. ## EndpointStatus #### Values --- * ``ENABLED`` * --- * ``DISABLED`` * ## EndpointType #### Values --- * ``WEBHOOK`` * --- * ``ACH_PROCESSOR`` * ## EntryIndex Indexes for querying Entries. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``ENTRY_ID`` * Index by `entryId` field. Must supply an `entryId: { eq: }` filter to the `where` object. --- * ``TRANSACTION_ID`` * Index by `transactionId` field. Must supply an `transactionId: { eq: }` filter to the `where` object. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. ## ExcludeTableEnum #### Values --- * ``Account`` * --- * ``AccountContext`` * --- * ``AccountSet`` * --- * ``AccountSetMember`` * --- * ``AttachedCalculation`` * --- * ``Balance`` * --- * ``BulkExecution`` * --- * ``Calculation`` * --- * ``Endpoint`` * --- * ``Entry`` * --- * ``Journal`` * --- * ``Transaction`` * --- * ``TransactionException`` * --- * ``TranCode`` * --- * ``VelocityControl`` * --- * ``VelocityControlAccount`` * --- * ``VelocityLimit`` * --- * ``WorkflowExecution`` * ## ExportCompression #### Values --- * ``NONE`` * --- * ``GZIP`` * --- * ``BZIP2`` * --- * ``ZSTD`` * ## ExportEntity #### Values --- * ``Balance`` * --- * ``Account`` * --- * ``AccountSet`` * --- * ``Transaction`` * --- * ``Entry`` * --- * ``AccountSetMember`` * --- * ``WorkflowExecution`` * ## ExportFormat #### Values --- * ``PARQUET`` * --- * ``JSON`` * --- * ``CSV`` * ## ExportVersion #### Values --- * ``LATEST`` * --- * ``HISTORICAL`` * ## FileRecordType #### Values --- * ``FILE`` * --- * ``BATCH`` * --- * ``IAT_BATCH`` * --- * ``ENTRY_DETAIL`` * --- * ``ADV_ENTRY_DETAIL`` * --- * ``IAT_ENTRY_DETAIL`` * ## ISO8583ProcessorType #### Values --- * ``UNSPECIFIED`` * --- * ``VISA_DIRECT`` * --- * ``GALILEO`` * --- * ``MARQETA`` * --- * ``LITHIC`` * --- * ``HIGHNOTE`` * --- * ``Q2`` * --- * ``FIRST_DATA`` * --- * ``I2C`` * ## IndexDataType #### Values --- * ``INT`` * --- * ``UINT`` * --- * ``DOUBLE`` * --- * ``BOOL`` * --- * ``STRING`` * --- * ``BYTES`` * --- * ``DURATION`` * --- * ``TIMESTAMP`` * --- * ``UUID`` * --- * ``DATE`` * --- * ``MONEY`` * --- * ``DECIMAL`` * ## IndexOnEnum Record types which support custom indexes. #### Values --- * ``Account`` * --- * ``AccountSet`` * --- * ``Balance`` * --- * ``Transaction`` * --- * ``TranCode`` * --- * ``Entry`` * --- * ``KV`` * --- * ``View`` * Target a user-defined view. Requires `viewName` on createIndex / deleteIndex. ## IndexStatusEnum #### Values --- * ``CREATING`` * Index is creating and backfilling. --- * ``ACTIVE`` * Index is active ## JobType #### Values --- * ``SETTLE_WORKFLOW`` * ## JournalIndex Indexes for querying Journals. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``JOURNAL_ID`` * Index by `JOURNAL_ID` field. Must supply a `journalId: { eq: }` filter to the `where` object. --- * ``NAME`` * Index by `name` field. Use to apply query filters on the value of `name`. --- * ``STATUS`` * Index by `status` field. Use to apply query filters on the value of `status`. --- * ``CODE`` * Index by `code` field. Use to apply query filters on the value of `code`. ## KVIndex #### Values --- * ``Namespace`` * Query the built-in namespace index. --- * ``Custom`` * Query a user-defined custom index created on `KV`. ## Layer The ledger can apply a entries to one of three layers: SETTLED, PENDING, and ENCUMBRANCE. The SETTLED layer is what is actually fully settled. The PENDING layer is what's settled but also includes holds and pending charges. This can be used to verify the account will have enough funds after the holds and pending transactions have cleared. The ENCUMBRANCE layer allows us to add future transactions that are scheduled and also goals or budgeting tools to set money aside in the account. #### Values --- * ``SETTLED`` * --- * ``PENDING`` * --- * ``ENCUMBRANCE`` * ## OpenToBuyType #### Values --- * ``AVAILABLE_ENCUMBRANCE`` * Available encumbrance balance in the normality of the account. --- * ``AVAILABLE_PENDING`` * Available pending balance in the normality of the account. --- * ``AVAILABLE_SETTLED`` * Available settled balance in the normality of the account. --- * ``VELOCITY_BALANCE`` * A default windowed attached velocity control. ## OpensearchSchemaBinaryMappingType #### Values --- * ``BINARY`` * ## OpensearchSchemaBooleanMappingType #### Values --- * ``BOOLEAN`` * ## OpensearchSchemaDateMappingType #### Values --- * ``DATE`` * --- * ``DATE_NANOS`` * ## OpensearchSchemaNumericMappingType #### Values --- * ``BYTE`` * --- * ``DOUBLE`` * --- * ``FLOAT`` * --- * ``HALF_FLOAT`` * --- * ``INTEGER`` * --- * ``LONG`` * --- * ``UNSIGNED_LONG`` * --- * ``SHORT`` * ## OpensearchSchemaObjectMappingType #### Values --- * ``OBJECT`` * ## OpensearchSchemaStringMappingType #### Values --- * ``KEYWORD`` * --- * ``TEXT`` * --- * ``MATCH_ONLY_TEXT`` * --- * ``TOKEN_COUNT`` * --- * ``WILDCARD`` * ## ParamDataType Data type of a parameter. #### Values --- * ``STRING`` * --- * ``INTEGER`` * --- * ``DECIMAL`` * --- * ``BOOLEAN`` * --- * ``UUID`` * --- * ``DATE`` * --- * ``TIMESTAMP`` * --- * ``JSON`` * ## PolicyAction #### Values --- * ``SELECT`` * --- * ``INSERT`` * --- * ``UPDATE`` * --- * ``DELETE`` * ## PolicyEffect #### Values --- * ``ALLOW`` * --- * ``DENY`` * ## RestoreStatusEnum #### Values --- * ``EXPORTING`` * --- * ``IMPORTING`` * --- * ``COMPLETE`` * --- * ``ERROR`` * ## RoundingMode Defines the rounding behavior when formatting units. #### Values --- * ``HALF_DOWN`` * Rounds up if the next digit is > 5, otherwise rounds down. --- * ``HALF_UP`` * Rounds up if the next digit is >= 5, otherwise rounds down. --- * ``DOWN`` * Rounds towards 0, truncating extra digits. --- * ``UP`` * Rounds away from 0. ## SQLField_Type #### Values --- * ``IS_NULL`` * --- * ``BYTES`` * --- * ``BOOL`` * --- * ``DOUBLE`` * --- * ``INT`` * --- * ``STRING`` * ## SortOrder `ASC` (ascending) or `DESC` (descending). #### Values --- * ``ASC`` * --- * ``DESC`` * ## SqlStatementStatus #### Values --- * ``ABORTED`` * --- * ``ALL`` * --- * ``FAILED`` * --- * ``FINISHED`` * --- * ``PICKED`` * --- * ``STARTED`` * --- * ``SUBMITTED`` * ## Status Record status. All records are `ACTIVE` by default. To avoid rewriting accounting history, most records are not deleted but simply marked `LOCKED`, indicating that they should not be used. #### Values --- * ``ACTIVE`` * --- * ``LOCKED`` * --- * ``INACTIVE`` * ## TranCodeIndex Indexes for querying TranCodes. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``TRAN_CODE_ID`` * Index by `tranCodeId` field. Must supply a `tranCodeId: { eq: }` filter to the `where` object. --- * ``CODE`` * Index by `code` field. Use to apply query filters on the value of `code`. --- * ``STATUS`` * Index by `status` field. Use to apply query filters on the value of `status`. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. ## TransactionIndex Indexes for querying Transactions. To optimize query performance and apply desired filters, choose the appropriate index. #### Values --- * ``TRANSACTION_ID`` * Index by `TRANSACTION_ID` field. Must supply a `transactionId: { eq: }` filter to the `where` object. --- * ``CORRELATION_ID`` * Index by `CORRELATION_ID` field. Must supply a `correlationId: { eq: }` filter to the `where` object. --- * ``EXTERNAL_ID`` * Index by `EXTERNAL_ID` field. Must supply an `externalId: { eq: }` filter to the `where` object. --- * ``CUSTOM`` * Use a custom-defined index. Must supply a `custom` filter to the `where` object. --- * ``SEARCH`` * Use eventually consisent search. Must supply a `search` filter to the `where` object. --- * ``TRANSACTION_IDS`` * Retrieve a list of transactions by id. Must supply an `ids` filter to the `where` object. --- * ``GROUP`` * Retrieve a list of transactions by group. Must supply a `group` filter to the `where` object. ## TxIsolation Transaction isolation level. Different isolation levels provide different guarantees about data visibility and consistency. #### Values --- * ``READ_COMMITTED`` * Read committed isolation - allows reading only committed data --- * ``SNAPSHOT`` * Snapshot isolation - provides a consistent snapshot view of the database --- * ``REPEATABLE_READ`` * Repeatable read isolation - prevents non-repeatable reads --- * ``SERIALIZABLE`` * Serializable isolation - strictest isolation level ## UploadType #### Values --- * ``BULK_GRAPHQL_VARIABLES`` * --- * ``ACH`` * ## VelocityControlIndex #### Values --- * ``VELOCITY_CONTROL_ID`` * Index by `velocityControlId` field. Must supply an `velocityControlId: { eq: }` filter to the `where` object. --- * ``NAME`` * Index by `name` field. Use to apply query filters on the value of `name`. --- * ``ACCOUNT_ID`` * Index by `accountId` attached to velocity control. Must supply an `accountId: { eq: }` filter to the `where` object. --- * ``VELOCITY_LIMIT_ID`` * ## VelocityEnforcementAction #### Values --- * ``WARN`` * Returns a selectable exception on postTransaction.exceptions, but allows transaction to be posted. --- * ``VOID`` * Returns a selectable exception on postTransaction.exceptions, and voids offending transaction. --- * ``REJECT`` * Returns an exception as an error, aborting entire request. ## VelocityLimitIndex #### Values --- * ``VELOCITY_LIMIT_ID`` * Index by `velocityLimitId` field. Must supply an `velocityLimitId: { eq: }` filter to the `where` object. --- * ``NAME`` * Index by `name` field. Use to apply query filters on the value of `name`. ## ViewEntity Enum of source tables that can trigger view updates. #### Values --- * ``Account`` * --- * ``AccountSet`` * --- * ``Balance`` * --- * ``Entry`` * --- * ``Transaction`` * --- * ``TranCode`` * ## ViewTriggerEnum #### Values --- * ``OnSelect`` * --- * ``OnInsert`` * --- * ``OnUpdate`` * --- * ``OnDelete`` * --- # Input Types Input types are used as arguments for mutations and queries to provide input data to an operation. ## AccountConfigInput Fields to create a system configuration for an account. #### Input Fields --- * ``enableConcurrentPosting`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, allow concurrent posting to the account. See `BalanceType` for balance retrieval options available for concurrent-enabled accounts. Defaults to `false`. --- * ``upsert`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true` use an upsert on the accountId index to upsert and avoid unique constraint violation. If account already created, the existing account is unchanged. --- * ``idempotent`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Enables idempotent account creation. When true, if an account with this ID already exists, the original creation arguments are compared against the request. If they match, the existing account is returned instead of failing with a unique constraint violation. Guarantees: - Idempotency is keyed on `accountId` — the caller must supply a stable ID. - The creation arguments (name, code, description, normalBalanceType, status, externalId, metadata, enableConcurrentPosting) must match the original creation. A mismatch fails with `BAD_REQUEST`. - Each entry in `accountSetIds` is validated against the existing memberships. If the account is not already a member of every requested set, the request fails with `BAD_REQUEST`. Cannot be used together with `upsert`. ## AccountEntriesFilterInput Filter conditions for entries on an Account. Since accountId is already known from the parent Account, only journalId and currency filtering is needed. #### Input Fields --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter by journal ID. If omitted, entries from all journals are returned. --- * ``currency`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter by currency. Defaults to USD if not specified. ## AccountFilterInput Filter conditions to apply to an account query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``accountId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `accountId` field. Required when using index `AccountIndex.ACCOUNT_ID`. --- * ``externalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `externalId` field. Required when using index `AccountIndex.EXTERNAL_ID`. --- * ``name`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `name` field. Only available when using index `AccountIndex.NAME`. --- * ``code`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `code` field. Only available when using index `AccountIndex.CODE`. --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `status` field. Only available when using index `AccountIndex.STATUS`. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `AccountIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `AccountIndex.SEARCH`. --- * ``codeUnique`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `code` field. Required when using index `AccountIndex.CODE_UNIQUE`. ## AccountIndexInput Specify the pre-defined AccountIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`AccountIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-index) * Indexes for querying Accounts. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## AccountInput Fields to create a new account. #### Input Fields --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the account. --- * ``externalId`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows specifying a unique external ID associated with this account. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Shorthand code for the account. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account name. --- * ``normalBalanceType`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Determines whether account should use a debit- or credit-normal balance. _Default:_ ``CREDIT`` --- * ``accountSetIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * IDs of AccountSets to add this account to. Adding memberships at create time is the preferred way to place new accounts in sets: a brand-new account has no balance and nothing in flight, so the membership is active immediately — no settle window and no write intents on set rows. Adding a funded account later (`addToAccountSet`) takes write intents on the target set and any non-concurrent ancestors, so funded adds into the same set — or sharing a non-concurrent ancestor — serialize under churn; different sets under a shared concurrent rollup stay parallel. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account. --- * ``status`` - [`Status!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Current status for the account. _Default:_ ``ACTIVE`` --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account. --- * ``config`` - [`AccountConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-config-input) * System config for the account. ## AccountSetConfigInput Fields to create a system configuration for an account set. #### Input Fields --- * ``enableConcurrentPosting`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, allow concurrent posting to the account. See `BalanceType` for balance retrieval options available for concurrent-enabled accounts. Defaults to `false`. --- * ``upsert`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true` use an upsert on the accountSetId index to upsert and avoid unique constraint violation. If account set already created, the existing account set is unchanged. --- * ``idempotent`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Enables idempotent account set creation. When true, if an account set with this ID already exists, the original creation arguments are compared against the request. If they match, the existing account set is returned instead of failing with a unique constraint violation. Guarantees: - Idempotency is keyed on `accountSetId` — the caller must supply a stable ID. - The creation arguments (name, description, journalId, normalBalanceType, code, metadata, enableConcurrentPosting) must match the original creation. A mismatch fails with `BAD_REQUEST`. - Each entry in `accountSetIds` is validated against the existing memberships. If the account set is not already a member of every requested set, the request fails with `BAD_REQUEST`. Cannot be used together with `upsert`. ## AccountSetEntriesFilterInput Filter conditions for entries on an AccountSet. Since accountId and journalId are already known from the parent AccountSet, only currency filtering is needed. #### Input Fields --- * ``currency`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter by currency. Defaults to USD if not specified. ## AccountSetFilterInput Filter conditions to apply to an account set query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``accountSetId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `accountSetId` field. Required when using index `AccountSetIndex.ACCOUNT_SET_ID`. --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Specify the Journal to use with `eq`. Required for all indexes. --- * ``name`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `name` field. Only available when using index `AccountSetIndex.NAME`. --- * ``code`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Fitler on the `code` field. Only available when using index `AccountSetIndex.CODE`. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `AccountSetIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `AccountSetIndex.SEARCH`. ## AccountSetIndexInput Specify the pre-defined AccountSetIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`AccountSetIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-set-index) * Indexes for querying AccountSets. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## AccountSetInput Fields to create a new account set. #### Input Fields --- * ``accountSetId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the set. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The journal for the set. If omitted, the default journal will be used. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the set. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account set. --- * ``normalBalanceType`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Determines whether the account set should use a debit- or credit-normal balance. _Default:_ ``CREDIT`` --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account set. --- * ``config`` - [`AccountSetConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-config-input) * System config for the account set. --- * ``accountSetIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * IDs of AccountSets to add this account set to. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Shorthand code for the account set. If not provided, a default code will be generated. ## AccountSetMemberInput #### Input Fields --- * ``memberType`` - [`AccountSetMemberType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-set-member-type) * Whether the member to add is an Account or AccountSet --- * ``memberId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Identifier for the member to add. When adding accounts, this is the `accountId`. When adding account sets, this is the `accountSetId`. ## AccountSetMembersFilterInput Filter conditions to apply when querying members of an account set. #### Input Fields --- * ``accountSetId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `accountSetId` field. --- * ``memberId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `memberId` field: the UUID of a member `Account` or `AccountSet`. ## AccountSetUpdateInput AccountSet fields to update. #### Input Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the set. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account set. --- * ``normalBalanceType`` - [`DebitOrCredit`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Determines whether the account set should use a debit- or credit-normal balance. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account set. --- * ``config`` - [`AccountSetConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-set-config-input) * System config for the account set. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Shorthand code for the account set. ## AccountUpdateInput Account fields to update. #### Input Fields --- * ``externalId`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows specifying a unique external ID associated with this account. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Shorthand code for the account. --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account name. --- * ``normalBalanceType`` - [`DebitOrCredit`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Determines whether account should use a debit- or credit-normal balance. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account. --- * ``status`` - [`Status`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Current status for the account. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account. --- * ``config`` - [`AccountConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#account-config-input) * System config for the account. ## AchCreateConfigurationInput #### Input Fields --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this configuration. --- * ``endpointId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Endpoint to use for decisioning this ACH file. Required unless `autoPending` is set. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to post settlements into. --- * ``settlementAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Settlement Account. --- * ``exceptionAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an exception occurs, such as a Velocity Control or Account in a locked state. Funds in this account will be returned. --- * ``suspenseAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an account is not found. Funds in this account will be returned. --- * ``feeAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Fee Account. Required unless `direction` is `RDFI`. --- * ``odfiHeaderConfiguration`` - [`AchOdfiHeaderConfigurationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-odfi-header-configuration-input) * ACH Processor information for files. --- * ``timeZone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``direction`` - [`AchConfigurationDirection`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-configuration-direction) * The direction of ACH files this configuration processes. Defaults to `BOTH`. --- * ``autoPending`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, RDFI entries skip the create webhook and are automatically posted as PENDING to `pendingAccountId`, awaiting manual settlement or return. Not valid for `ODFI` configurations. Defaults to false. --- * ``pendingAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post auto-pending entries to. Required when `autoPending` is set. --- * ``traceNumberConfiguration`` - [`AchTraceNumberConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-trace-number-configuration-input) * Optional reserved range for Twisp-generated trace numbers. Use this when trace numbers originated outside of Twisp share the ODFI's trace number space. If omitted Twisp generates trace numbers from 1 to 9999999. --- * ``fileModifierConfiguration`` - [`AchFileModifierConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-file-modifier-configuration-input) * Optional file ID modifier configuration. Use this when files originated outside of Twisp share the ODFI's file ID modifier space for the day: either reserve a range Twisp generates from, following the generation sequence A-Z then 0-9, or set `userSupplied` and assign the modifier of each file yourself. If omitted Twisp generates modifiers from A through 9. --- * ``offsetConfiguration`` - [`AchOffsetConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-offset-configuration-input) * When set, originated files are balanced: each batch carries an offset entry drawn on the configured account so file credits equal file debits. If omitted, originated files are unbalanced. ## AchFileInfoFilterInput #### Input Fields --- * ``configId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``processingStatus`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``created`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` ## AchFileInfoIndexInput #### Input Fields --- * ``name`` - [`AchFileInfoIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-info-index) * ## AchFileModifierConfigurationInput The file ID modifier configuration of an ACH configuration. The full range — `startFileIdModifier` A, `endFileIdModifier` 9 — is Twisp's own default, so setting it stores no configuration at all and resets one already set. #### Input Fields --- * ``startFileIdModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Inclusive first file ID modifier Twisp assigns each day. A single character from A-Z or 0-9. Required unless `userSupplied` is true. --- * ``endFileIdModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Inclusive last file ID modifier Twisp assigns each day. A single character from A-Z or 0-9 at or after `startFileIdModifier` in the generation sequence A-Z then 0-9. Equal to `startFileIdModifier` reserves a single modifier: one file per day. Required unless `userSupplied` is true. --- * ``userSupplied`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, the caller assigns the file ID modifier: every [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.generate-file) call must carry `options.fileModifier`, and Twisp assigns no modifiers of its own. May not be combined with `startFileIdModifier` or `endFileIdModifier`. ## AchGenerateFileInput #### Input Fields --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The configuration to use for generating return file. --- * ``fileKey`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The key to store this file. --- * ``fileType`` - [`AchFileType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-type) * The type of file to generate. --- * ``generateEmpty`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * If true, generate empty files. Defaults to true. _Default:_ ``true`` --- * ``options`` - [`AchGenerateFileOptionsInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-generate-file-options-input) * Additional file generation options. ## AchGenerateFileOptionsInput #### Input Fields --- * ``fileHeaderReferenceCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Value for the Reference Code field of the generated file's header record (positions 87-94). The ACH specification reserves this field for information pertinent to the Originator; it has no effect on processing. Up to 8 printable ASCII characters, with no leading or trailing spaces. Shorter values are right-padded with spaces. When omitted, the field is space-filled. _Example:_ ``"REF00001"`` --- * ``fileModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * File ID modifier for the generated file's header record (position 34). A single character from A-Z or 0-9, unique among the files created that day with the same origin and destination. Required when the configuration's `fileModifierConfiguration` sets `userSupplied`. Rejected otherwise, since Twisp then assigns the modifier from its configured range. _Example:_ ``"B"`` ## AchOdfiHeaderConfigurationInput #### Input Fields --- * ``immediateDestination`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateDestinationName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOrigin`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOriginName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## AchOffsetConfigurationInput #### Input Fields --- * ``routingNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Routing number of the account the offset entry is drawn on. Defaults to the configuration's `immediateOrigin`, which must then be a valid ABA routing number. --- * ``accountNumber`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account number the offset entry is drawn on. --- * ``accountType`` - [`AchOffsetAccountType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-offset-account-type) * Type of the offset account. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional discretionary data for the offset entry (2 characters). --- * ``enableBalancedReturnNOCs`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, generated return and NOC files are balanced as well: each return batch carries an offset entry drawn on the offset account. Defaults to false — only originated forward files are balanced. ## AchProcessFileInput #### Input Fields --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Configuration to use to process this file. --- * ``fileKey`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The file key to use for this file. --- * ``fileType`` - [`AchFileType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-type) * The type of file being processed. --- * ``options`` - [`AchProcessFileOptionsInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-process-file-options-input) * Additional ACH processing options. ## AchProcessFileOptionsInput #### Input Fields --- * ``preprocessedFileKey`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Output file key for preprocessed files. --- * ``preprocessedExcludedFileKey`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optionally output file key for excluded preprocessed entries. ## AchTraceNumberConfigurationInput #### Input Fields --- * ``minTraceNumber`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Minimum trace number Twisp will generate. Must be greater than or equal to 1. --- * ``maxTraceNumber`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Maximum trace number Twisp will generate. Must be greater than `minTraceNumber` and less than or equal to 9999999. ## AchUpdateConfigurationInput #### Input Fields --- * ``endpointId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Endpoint to use for decisioning this ACH file. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to post settlements into. --- * ``settlementAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Settlement Account. --- * ``exceptionAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an exception occurs, such as a Velocity Control or Account in a locked state. Funds in this account will be returned. --- * ``suspenseAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an account is not found. Funds in this account will be returned. --- * ``feeAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Fee Account. --- * ``odfiHeaderConfiguration`` - [`AchOdfiHeaderConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-odfi-header-configuration-input) * ACH Processor information for files. **Note:** replaces existing `odfiHeaderConfiguration` --- * ``timeZone`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``direction`` - [`AchConfigurationDirection`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-configuration-direction) * The direction of ACH files this configuration processes. --- * ``autoPending`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, RDFI entries skip the create webhook and are automatically posted as PENDING to `pendingAccountId`, awaiting manual settlement or return. Not valid for `ODFI` configurations. --- * ``pendingAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post auto-pending entries to. Required when `autoPending` is set. --- * ``traceNumberConfiguration`` - [`AchTraceNumberConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-trace-number-configuration-input) * Optional reserved range for Twisp-generated trace numbers. **Note:** replaces existing `traceNumberConfiguration` --- * ``fileModifierConfiguration`` - [`AchFileModifierConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-file-modifier-configuration-input) * Optional file ID modifier configuration: a reserved range Twisp generates from, or caller-supplied modifiers. The full range — `startFileIdModifier` A, `endFileIdModifier` 9 — resets the configuration to Twisp's default, which is how a range or `userSupplied` is cleared once set. **Note:** replaces existing `fileModifierConfiguration` --- * ``offsetConfiguration`` - [`AchOffsetConfigurationInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#ach-offset-configuration-input) * When set, originated files are balanced: each batch carries an offset entry drawn on the configured account so file credits equal file debits. **Note:** replaces existing `offsetConfiguration` --- * ``clearOffsetConfiguration`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, removes the offset configuration so originated files are no longer balanced. May not be combined with `offsetConfiguration`. ## AsVoidTransactionInput #### Input Fields --- * ``voidOf`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The ID of the transaction this transaction voids. ## AttachCalculationInput #### Input Fields --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to attach calculation to. This parameter is ignored when attaching to an account set. Defaults to the default journal if not provided when attaching to an account. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account or Account Set to attach calculation to. --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Calculation to attach. ## BalanceFilterInput Filter conditions to apply to a balance query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Specify the Journal to use with `eq`. If omitted, the default journal will be used. --- * ``accountId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `accountId` field. Required when using index `BalanceIndex.ACCOUNT_ID`. --- * ``currency`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `currency` field. --- * ``calculationId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on `calculationId` field when using `BalanceIndex.DIMENSION` --- * ``dimension`` - [`DimensionFilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#dimension-filter-value) * Filter on `dimension` field when using `BalanceIndex.Dimension` --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `BalanceIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `BalanceIndex.SEARCH`. ## BalanceHistoryFilterInput Filter conditions to apply to a balance history query. #### Input Fields --- * ``modified`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `modified` timestamp. --- * ``committed`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the transaction commit timestamp for the specific balance record version. ## BalanceIndexInput Specify the pre-defined BalanceIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`BalanceIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#balance-index) * Indexes for querying Balances. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## BalanceLimitInput #### Input Fields --- * ``layer`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The layer this balance limit is enforced at. Must resolve to `SETTLED`, `PENDING` or `ENCUMBRANCE`. --- * ``amount`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The maximum amount at this layer that can be spent. Must resolve to a decimal. --- * ``normalBalanceType`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The direction this balance enforces on as an upper limit. Must resolve to `CREDIT` or `DEBIT`. --- * ``start`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The timestamp at which this balance limit begins to be effective. If provided, must resolve to a `timestamp`. Defaults to the creation stamp of the underlying control. @example("timestamp('2022-01-01T14:00:00.000Z')") --- * ``end`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The timestamp at which this balance limit ceases to be effective. If provided, must resolve to a `timestamp`. Defaults to infinite timestamp. @example("timestamp('2022-01-01T15:00:00.000Z')") ## BatchExecuteStatementInput #### Input Fields --- * ``sqls`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Between #### Input Fields --- * ``begin`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``end`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## BranchInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the new tenant, used for display purposes and easier identification. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the new tenant, providing additional context about its purpose or characteristics. --- * ``include`` - [`[BranchIncludeEnum]`](https://www.twisp.com/docs/reference/graphql/types/enum.md#branch-include-enum) * Entity classes to copy. When omitted or empty, every entity class is copied. Custom indexes defined on a view require `View` to be included as well, since the index cannot be created without the table backing the view. --- * ``ephemeral`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Create the branch as an ephemeral tenant that will be automatically deleted after 60 days. _Default:_ ``false`` ## BulkQueryExecutionFilterInput Filter conditions to apply to a bulk execution query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `status` field. Required when using index `BulkQueryExecutionIndex.STATUS`. --- * ``created`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `created` field. Available as sort key on `BulkQueryExecutionIndex.STATUS`. ## BulkQueryExecutionIndexInput Specify the pre-defined BulkQueryExecutionIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`BulkQueryExecutionIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#bulk-query-execution-index) * Indexes for querying bulk executions. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## BulkQueryInput #### Input Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this bulk execution. _Default:_ ``"Bulk Query"`` --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Key to file to execute. --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique Identifier for this execution of a bulk query. --- * ``query`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Parameterized GraphQL query string to execute. --- * ``transform`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional jq transform to run on variables in file identified by `key`. The result of the transform must be a list of json variables. @example("map(.accountId)") ## CalculationConfigInput #### Input Fields --- * ``enableEffectiveBalances`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Enable effective date calculations. Creates 3 child calculations for YYYY, YYYY_MM, and YYYY_MM_DD. Effective date dimensions are prepended to custom dimensions. _Default:_ ``false`` --- * ``effectiveDateSource`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression resolving to a date, used as the base for effective date dimensions. Defaults to context.vars.transaction.effective when empty. Requires enableEffectiveBalances to be true. ## CalculationFilterInput #### Input Fields --- * ``calculationId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``code`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` ## CalculationIndexInput #### Input Fields --- * ``name`` - [`CalculationIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#calculation-index) * --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## CalculationUpdateInput #### Input Fields --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique shorthand code for this calculation. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this calculation. ## CancelStatementInput #### Input Fields --- * ``id`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## CardInitializeInput #### Input Fields --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The unique identifier for the journal that card transactions will post to by default. If omitted, the default journal will be used. --- * ``settlementAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * A unique identifier to an existing settlement account that card transactions will post to by default. If not provided, a default card transaction account will be used as the settlement account. ## CreateAliasInput #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The raw alias name. `x-twisp-account-id` qualifies it with an `alias/` prefix. Alias names are first-come-first-served within a region: creation fails when another organization already claimed the name. The name follows the S3 bucket naming rules: 3 to 63 characters of lowercase letters, numbers, periods, and hyphens, beginning and ending with a letter or a number, with no two adjacent periods, and not formatted as an IP address. --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The accountId the alias resolves to. --- * ``ttlSeconds`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * How long, in seconds, servers may cache the alias resolution. Omit or zero for the server's default cache TTL. ## CreateCalculationInput #### Input Fields --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this calculation. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique shorthand code for this balance calculation. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this calculation. --- * ``scope`` - [`CalculationScope!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#calculation-scope) * The calculation scope of this calculation. Defaults to `GLOBAL`. _Default:_ ``GLOBAL`` --- * ``dimensions`` - [`[PartitionKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#partition-key-input) * Group by these values to index the calculation. The `account`, `transaction` and `entry` are available for use in the dimension computation on `context.vars`. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if an balance entry should be written. The `account`, `transaction`, `tranCode` and `entry` are available for use in the dimension computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``config`` - [`CalculationConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#calculation-config-input) * Configuration options for this calculation. ## CreateClientInput #### Input Fields --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Principal that this client applies to. If you're supplying your own OIDC this will be the `iss` claim on your JWT. If using Twisp IAM/OIDC token exchange, this will be the IAM principal you signed with, typically a role ARN. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique name of the client. --- * ``policies`` - [`[PolicyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#policy-input) * The policies to evaluate. ## CreateGroupInput #### Input Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the group. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the group, such as 'Admins' or 'DataAnalysts'. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the group's purpose, intended to provide additional context. --- * ``policy`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A set of policies to apply to this group, formatted as a JSON list that define the permissions granted to users within this group. The structure of these policies matches the Policy type, but serialized as a JSON string. Example: ``` policy: "[{\"actions\": [\"*\"],\"effect\": \"DENY\",\"resources\":[\"*\"],\"assertions\": {\"always false\": \"1 == 0\"}}]" ``` ## CreateIndexInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``on`` - [`IndexOnEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * The type of record this index applies to. --- * ``viewName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the target view. Required when `on: View`; ignored otherwise. --- * ``async`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is populated asynchronously. --- * ``unique`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is unique. --- * ``partition`` - [`[PartitionKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#partition-key-input) * The partition key used for this index. --- * ``partitionShardCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Specifies the number of shards for partition write scaling. This parameter defines how many shards the partition key is automatically split into, similarly to RAID-style disk striping. Increasing this value allows the index to distribute write throughput across multiple shards while sacrificing global sort order on the partition. For instance, setting `partitionShardCount` to 4 splits each unique partition into four shards, effectively allowing 4000 writes per second for a single partition key. --- * ``sort`` - [`[IndexKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#index-key-input) * The sort key to use for supporting range queries. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. ## CreateScheduleInput #### Input Fields --- * ``jobType`` - [`JobType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#job-type) * The job type to create the schedule for. Currently only one schedule per job-type is supported. --- * ``jobName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A job name that's unique per job type. --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The Twisp principal to run the job on a schedule. This should have a matching `client` policy. --- * ``scheduleExpression`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A schedule expression to run this job on. cron/rate/once supported see https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html for valid syntax. --- * ``timezone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The timezone to run this schedule on based on https://www.iana.org/time-zones example: "America/Los_Angeles" or "UTC" Supports ST rules defined in https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html --- * ``metadata`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON metadata to pass to running job. ## CreateSearchIndexInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``on`` - [`IndexOnEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * The type of record this index applies to. --- * ``viewName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the target view. Required when `on: View`; ignored otherwise. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. --- * ``opensearchSchema`` - [`OpensearchSchemaInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-input) * Opensearch mapping (with CEL expressions) applied to the document prior to indexing. Required. Every search index must declare its field types explicitly so that sort, filter, and aggregation behavior is stable across index creations. Indexes created without a schema rely on Opensearch dynamic mapping defaults, which have drifted over time and across Opensearch Serverless versions, producing cursors and sort behaviors that are not portable between indexes — so this path is no longer supported. ## CreateTenantInput #### Input Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the tenant. --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A globally unique identifier representing an environment within the organization. This accountId, when combined with an AWS region, is used to calculate the database tenant. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the tenant, used for display purposes and easier identification. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the tenant, providing additional context about its purpose or characteristics. --- * ``ephemeral`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Create an ephemeral tenant that will be automatically deleted after 60 days. _Default:_ ``false`` ## CreateUpload #### Input Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of file. e.g. `path/to/file.json` --- * ``uploadType`` - [`UploadType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#upload-type) * The type of upload: `BULK_GRAPHQL_VARIABLES` - The content-type is `application/json` and is an array of json objects for a bulk graphql query execution. `ACH` - The content-type is `text/plain` and is a NACHA formatted text file. _Default:_ ``BULK_GRAPHQL_VARIABLES`` --- * ``contentType`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * `contentType` of file. --- * ``contentEncoding`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * `contentEncoding` of file. Only `gzip` is supported. Only allowed for `BULK_GRAPHQL_VARIABLES` uploads. ## CreateUserInput #### Input Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the user. --- * ``groupIds`` - [`[UUID!]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * A list of unique identifiers for the groups to which the user belongs. The user's permissions are determined by the combined policies of these groups. --- * ``email`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The user's email address, which serves as a unique identifier and primary means of contact. ## CreateViewInput Input for creating a new view materialized view. #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this view. Will be used as the table name in the public namespace. Should be a short, human-readable name. --- * ``document`` - [`[DocumentElementInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#document-element-input) * Cel Expressions and Type that define the aggregation. `context.source` will have the triggering document. --- * ``sources`` - [`[ViewSourceInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-source-input) * List of source tables that trigger updates to this view. When records in these tables are inserted, updated, or deleted, the view will be recalculated. --- * ``partition`` - [`[PartitionKeyInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#partition-key-input) * Partition for this aggregation. Use `context.source` for defining the index. --- * ``sort`` - [`[IndexKeyInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#index-key-input) * Sort for this aggregation. Use `context.source` for defining the index. --- * ``filters`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions that filter when the view should be updated. Only source changes that satisfy all filter conditions will trigger an update to the view. Each expression must return a boolean value. Default: { enabled: "true" } (all changes trigger an update) --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this view. _Default:_ ``""`` --- * ``config`` - [`ViewConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-config-input) * Extra config options for view. --- * ``normalize`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A CEL expression to normalize the source object by. If provided, must evaluate to a list. The trigger will be repeated for each item in the list and the value will be available on `context.trigger.normalize`. If evaluates to an empty list, will behave as if the normalize expression not provided. --- * ``indexes`` - [`[ViewIndexInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-index-input) * --- * ``searchIndexes`` - [`[ViewSearchIndexInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-search-index-input) * ## CustomIndexFilter Query conditions for a custom index. #### Input Fields --- * ``index`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The `name` of the custom index to use. --- * ``partition`` - [`[CustomIndexFilterValue]`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter-value) * Query conditions for specifying the index partition to use. --- * ``sort`` - [`[CustomIndexFilterValue]`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter-value) * Query conditions for specifying sort order. ## CustomIndexFilterValue Filter conditionals for querying the partition or sort key of a custom index. #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Identifier for the key to apply the filter to. --- * ``value`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditions to apply at this key. ## DescribeStatementInput #### Input Fields --- * ``id`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## DescribeTableInput #### Input Fields --- * ``database`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``maxResults`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``schema`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``table`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## DestinationInput #### Input Fields --- * ``files`` - [`FilesDestinationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#files-destination-input) * ## DetachCalculationInput #### Input Fields --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to detach calculation. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account or set to detach calculation. --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Calculation to detach. ## DimensionBetween #### Input Fields --- * ``begin`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``end`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. ## DimensionFilterValue #### Input Fields --- * ``eq`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``like`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``lt`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``lte`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``gt`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``gte`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``between`` - [`DimensionBetween`](https://www.twisp.com/docs/reference/graphql/types/input.md#dimension-between) * ## DocumentElementInput #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Alias for this element. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression for the value of this document element. _Example:_ ``"context.source.account_id"`` --- * ``type`` - [`CelType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#cel-type) * The type this document element resolves to. --- * ``listOfType`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * If `true` resolves the type as a list of `type` (i.e. `[type]`) _Default:_ ``false`` ## Effective #### Input Fields --- * ``cumulative`` - [`Date`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#date) * Cumulative account balance as of a particular effective date. _Example:_ ``"2023-10-17"`` --- * ``period`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account balance of a particular effective time period. Supported periods are in formats: `YYYY`, `YYYY-MM`, `YYYY-MM-DD`. Useful for reconciliation/balances files. _Example:_ ``"2023-10"`` --- * ``range`` - [`PeriodRange`](https://www.twisp.com/docs/reference/graphql/types/input.md#period-range) * Effective account balances over a range of time periods. Useful for income statement. _Example:_ ``{gte: "2023-10", lte: "2023-12"}`` --- * ``periods`` - [`Periods`](https://www.twisp.com/docs/reference/graphql/types/input.md#periods) * Per-period balances across the half-open interval `[gte, lt)`. Granularity is inferred from the format of `gte`/`lt` (`YYYY`, `YYYY-MM`, or `YYYY-MM-DD`); both bounds must use the same format and `lt` must be strictly greater than `gte`. With `accumulate: false` (default), each `effectiveBalances` entry is that period's own activity and the top-level balance is the sum across the range — useful for income-statement-style queries. With `accumulate: true`, each entry is the cumulative balance through the end of its period and the top-level balance is the closing cumulative just before `lt` — useful for daily statement snapshots and "as-of" queries. The opening balance for the range can be recovered either by querying the prior period with `cumulative`, or by subtracting the first entry's activity from its cumulative. _Example:_ ``{gte: "2024-03-01", lt: "2024-04-01", accumulate: true}`` --- * ``where`` - [`BalanceHistoryFilterInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#balance-history-filter-input) * Optional point-in-time filter for resolving historical effective balances. ## EndpointFilterInput #### Input Fields --- * ``endpointId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `endpointId` field. Required when using index `EndpointInded.ENDPOINT_ID`. --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `status` field. Only available when using index `EndpointIndex.STATUS`. ## EndpointIndexInput #### Input Fields --- * ``name`` - [`EndpointIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-index) * --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## EndpointInput Fields to create a new endpoint. #### Input Fields --- * ``endpointId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the endpoint. --- * ``status`` - [`EndpointStatus`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-status) * Current status of the endpoint. _Default:_ ``ENABLED`` --- * ``endpointType`` - [`EndpointType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-type) * The type of endpoint this endpoint is. _Default:_ ``WEBHOOK`` --- * ``url`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The url where this endpoint will transmit subscribed events to. --- * ``subscription`` - [`[String!]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A list of subscriptions that are available, supporting wildcards `*`. Format: `.` Supported entities: - journal - account - accountcontext - accountset - accountsetmember - trancode - transaction - entry - balance - customindex - custombalance - endpoint Supported ACH entities: - configuration - fileinfo - filerecord - workflowtrace --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * description of this endpoint. --- * ``filters`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying conditions for sending an event to the endpoint. Record is only sent if _all_ expressions evaluate to true, i.e. they are combined with a logical AND. Each expression must return a boolean value. ## EndpointUpdateInput Fields to update an existing endpoint. #### Input Fields --- * ``status`` - [`EndpointStatus`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-status) * Current status of the endpoint. --- * ``endpointType`` - [`EndpointType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-type) * The type of endpoint this endpoint is. --- * ``url`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The url where this endpoint will transmit subscribed events to. --- * ``subscription`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A list of subscriptions that are available, supporting wildcards `*`. Format: `.` Supported entities: - journal - account - accountcontext - accountset - accountsetmember - trancode - transaction - entry - balance - customindex - custombalance - endpoint Supported ACH entities: - configuration - fileinfo - filerecord - workflowtrace --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * description of this endpoint. --- * ``filters`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying conditions for sending an event to the endpoint. Record is only sent if _all_ expressions evaluate to true, i.e. they are combined with a logical AND. Each expression must return a boolean value. ## EntryFilterInput Filter conditions to apply to an entry query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``entryId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `entryId` field. Required when using index `EntryIndex.ENTRY_ID`. --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``currency`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``layer`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` --- * ``transactionId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `transactionId` field. Required when using index `EntryIndex.TRANSACTION_ID`. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `EntryIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `EntryIndex.SEARCH`. ## EntryIndexInput Specify the pre-defined EntryIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`EntryIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#entry-index) * Indexes for querying Entries. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## EntryUpdateInput Entry fields to update. #### Input Fields --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the entry. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this entry. ## ExecuteStatementInput #### Input Fields --- * ``sql`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ExecuteStatementSyncInput #### Input Fields --- * ``sql`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ExportInput #### Input Fields --- * ``entity`` - [`ExportEntity!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#export-entity) * Which Entity to export. --- * ``version`` - [`ExportVersion!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#export-version) * If `HISTORICAL`, exports every version of the entity. If `LATEST`, exports the latest version of the entity. --- * ``format`` - [`ExportFormat!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#export-format) * Output format for the export. Reccomend JSON or Parquet. --- * ``compression`` - [`ExportCompression!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#export-compression) * Compression options for the export. Recommend picking one, for lower read units. --- * ``destination`` - [`DestinationInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#destination-input) * Destination for export. Currently only files API supported. --- * ``formatOptions`` - [`FormatOptions`](https://www.twisp.com/docs/reference/graphql/types/input.md#format-options) * Additional formatting options for export files. --- * ``fromTimestamp`` - [`Timestamp`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Optionally define export from timestamp. Returns records which were created with `timestamp >= fromTimestamp` Used together with `toTimestamp` is the half open interval `fromTimestamp >= timestamp && timestamp < toTimestamp`. --- * ``toTimestamp`` - [`Timestamp`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Optionall define export to timestamp. Returns records which were created with `timestamp < toTimestamp` Used together with `fromTimestamp` is the half open interval `fromTimestamp >= timestamp && timestamp < toTimestamp`. ## FilesDestinationInput #### Input Fields --- * ``keyPrefix`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## FilterValue Conditional logic by which to apply a filter on a query. Each FilterValue object must contain just one key/value pair. Valid: `{ eq: "123" }`\ Invalid: `{ eq: "123", gt: "100" }` #### Input Fields --- * ``eq`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``like`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``lt`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``lte`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``gt`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``gte`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``between`` - [`Between`](https://www.twisp.com/docs/reference/graphql/types/input.md#between) * ## FormatOptions #### Input Fields --- * ``nullAs`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``header`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``delimiter`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## GetStatementResultInput #### Input Fields --- * ``id`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ISO8583CreateConfigInput #### Input Fields --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this configuration. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to post settlements into. --- * ``settlementAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ISO8583 Settlement Account. --- * ``timeZone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of this configuration. --- * ``processor`` - [`ISO8583ProcessorType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#iso8583processor-type) * Processor type for this configuration. --- * ``processorSpec`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Processor configuration. --- * ``openToBuyConfig`` - [`OpenToBuyConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#open-to-buy-config-input) * Balance to use for balance inquiry and partial authorizations. ## ISO8583UpdateConfigInput #### Input Fields --- * ``timeZone`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``openToBuyConfig`` - [`OpenToBuyConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#open-to-buy-config-input) * Balance to use for balance inquiry and partial authorizations. --- * ``processor`` - [`ISO8583ProcessorType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#iso8583processor-type) * Processor type for this configuration. --- * ``processorSpec`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Processor configuration. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of this configuration. ## IndexKeyInput Specify a named expression to sort the records within a custom index. Used for sorting and for querying by range conditions. #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Identifier for this key. Should be a short, human-readable name. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression which resolves to the value that is to be sorted. Within the expression, the `document` object represents the record. To sort by a field on the record, use `document.`. --- * ``sort`` - [`SortOrder!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * Whether the sort is in ascending or descending order. --- * ``type`` - [`IndexDataType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-data-type) * Optionally provide explicit type for value. Useful for metadata values which may be list of monomorphic types. _Example:_ ``"type: STRING"`` ## JournalConfigInput Fields to create a system configuration for a journal. #### Input Fields --- * ``enableEffectiveBalances`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, records point-in-time effective balances for all accounts in the journal. Defaults to `false`. ## JournalFilterInput Filter conditions to apply to a journal query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `journalId` field. Required when using index `JournalIndex.JOURNAL_ID`. --- * ``name`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `name` field. Only available when using index `JournalIndex.NAME`. --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `status` field. Only available when using index `JournalIndex.STATUS`. --- * ``code`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `code` field. Only available when using index `JournalIndex.CODE`. ## JournalIndexInput Specify the pre-defined JournalIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`JournalIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#journal-index) * Indexes for querying Journals. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## JournalInput Fields to create a new Journal. #### Input Fields --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the journal. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the journal. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the journal. --- * ``status`` - [`Status!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Operational status of the journal. _Default:_ ``ACTIVE`` --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional unique code for the journal. --- * ``config`` - [`JournalConfigInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#journal-config-input) * System config for the journal. ## JournalUpdateInput Journal fields to update. #### Input Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the journal. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the journal. --- * ``status`` - [`Status`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Operational status of the journal. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The code used to refer to this journal. ## KVFilterInput #### Input Fields --- * ``namespace`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the built-in `namespace` field. --- * ``key`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the built-in `key` field. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter on a custom index. ## KVIndexInput #### Input Fields --- * ``name`` - [`KVIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#kvindex) * Index to query. --- * ``sort`` - [`SortOrder!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * Sort order within the selected index. _Default:_ ``ASC`` ## KVPutInput #### Input Fields --- * ``namespace`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Namespace for the record. Max 512 UTF-8 bytes. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Key within the namespace. Max 512 UTF-8 bytes. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional description. Counts toward the 256 KiB persisted payload budget. --- * ``value`` - [`Value!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#value) * JSON payload to store. Together with `description`, must be <= 256 KiB. --- * ``conditions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * CEL conditions evaluated against the request context before the write is applied. `document` and `value` are bound to the current KV record (the version about to be replaced), or `null` when no record exists yet — so a create-only guard can be written as `document == null`. Condition expressions are persisted on the written `KVValue` for auditing, keyed by the map key. ## KVUpdateInput #### Input Fields --- * ``namespace`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Namespace for the record. Max 512 UTF-8 bytes. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Key within the namespace. Max 512 UTF-8 bytes. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * When set, replaces the stored description on the written version. When omitted, the existing description is preserved. Counts toward the 256 KiB persisted payload budget. --- * ``expressions`` - [`ExpressionValue!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-value) * Expression-valued RFC 7396 merge patch. String leaves are CEL expressions; non-string leaves are literal patch values. --- * ``conditions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * CEL conditions evaluated before the write. `document` and `value` are bound to the current KV record; `UpdateKv` fails with `NOT_FOUND` before conditions run when the record does not exist, so `document` is always non-null here. Condition expressions are persisted on the written `KVValue` for auditing, keyed by the map key. ## LimitInput #### Input Fields --- * ``timestampSource`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Uses a timestamp from the specified source for picking the balance limit. By default uses the system `transaction.timestamp`. Must resolve to a CEL `timestamp`. @example("timestamp(context.vars.transaction.?metadata.ts.orValue(context.transaction.timestamp))") --- * ``balance`` - [`[BalanceLimitInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#balance-limit-input) * ## ListDatabasesInput #### Input Fields --- * ``maxResults`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ListSchemasInput #### Input Fields --- * ``maxResults`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``schemaPattern`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``database`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ListStatementsInput #### Input Fields --- * ``maxResults`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``statementName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``status`` - [`SqlStatementStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sql-statement-status) * ## ListTablesInput #### Input Fields --- * ``maxResults`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``database`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``schemaPattern`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``tablePattern`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## LithicTransactionInput #### Input Fields --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the account this transaction will post to. --- * ``webhook`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The [Transaction](https://docs.lithic.com/docs/transactions) webhook object from Lithic. --- * ``journalId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the journal this transaction applies to. If not provided, defaults to the default journal that card transaction codes are configured with. --- * ``settlementAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier of the settlement account that transactions will settle from. If not provided, defaults to the default card settlement account. ## MoneyFormatInput Formatting options for money amounts. #### Input Fields --- * ``locale`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Locale represents a Unicode locale identifier. _Examples:_ ``'de-DE'``, ``'hi-IN'`` --- * ``groupDigits`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, whole digits will be grouped according to locale. For example, with locale `en-US` the number `1234567.89` is formatted with grouped digits as `1,234,567.89`. With other locales, these groupings may apply differently. _Default:_ ``false`` --- * ``addPlusSign`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, prefix the number with plus `+` symbol when the number is positive. Negative numbers are always displayed with a minus `-` symbol. _Default:_ ``false`` --- * ``roundingMode`` - [`RoundingMode!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#rounding-mode) * Defines the rounding behavior when the fractional units exceed the `maxDigits`. _Default:_ ``HALF_UP`` --- * ``currencyDisplay`` - [`CurrencyDisplay!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#currency-display) * Defines how to render the currency indicator. _Default:_ ``SYMBOL`` --- * ``minDigits`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Minimum number of fractional digits. When not specified, it will use the default fractional digits for the currency. For example, USD amounts default to 2 minimum digits. _Default:_ ``255`` --- * ``maxDigits`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Maximum number of fractional digits to show, which informs how rounding behavior is applied via the `roundingMode`. Defaults to 6. _Default:_ ``6`` ## MoneyInput #### Input Fields --- * ``units`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * Decimal is a fixed-precision data type supporting exact representation of numeric values. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * ISO 4217 standard three-character code indicating the currency. ## OpenToBuyConfigInput #### Input Fields --- * ``openToBuy`` - [`OpenToBuyType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#open-to-buy-type) * _Default:_ ``VELOCITY_BALANCE`` ## OpensearchSchemaBinaryMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaBinaryMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-binary-mapping-type) * --- * ``celExpression`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression to index for the document. _Example:_ ``"document.is_void"`` ## OpensearchSchemaBooleanMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaBooleanMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-boolean-mapping-type) * --- * ``celExpression`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A literal CEL expression to be evaluated. ## OpensearchSchemaDateMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaDateMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-date-mapping-type) * --- * ``celExpression`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression to index for the document. _Example:_ ``"document.effective"`` ## OpensearchSchemaInput #### Input Fields --- * ``mappings`` - [`OpensearchSchemaObjectMappingInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-object-mapping-input) * ## OpensearchSchemaMappingInput Use one of `binaryType`, `numericType`, `booleanType`,`dateType`, `objectType` or `stringType`. #### Input Fields --- * ``binaryType`` - [`OpensearchSchemaBinaryMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-binary-mapping-input) * --- * ``numericType`` - [`OpensearchSchemaNumericMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-numeric-mapping-input) * --- * ``booleanType`` - [`OpensearchSchemaBooleanMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-boolean-mapping-input) * --- * ``dateType`` - [`OpensearchSchemaDateMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-date-mapping-input) * --- * ``objectType`` - [`OpensearchSchemaObjectMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-object-mapping-input) * --- * ``stringType`` - [`OpensearchSchemaStringMappingInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-string-mapping-input) * ## OpensearchSchemaMappingsInput #### Input Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``value`` - [`OpensearchSchemaMappingInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-mapping-input) * Use one of `binaryType`, `numericType`, `booleanType`,`dateType`, `objectType` or `stringType`. ## OpensearchSchemaMultiFieldInput #### Input Fields --- * ``stringType`` - [`OpensearchSchemaStringMultiFieldInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-string-multi-field-input) * ## OpensearchSchemaMultiFieldsInput #### Input Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``value`` - [`OpensearchSchemaMultiFieldInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-multi-field-input) * ## OpensearchSchemaNumericMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaNumericMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-numeric-mapping-type) * --- * ``celExpression`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression to index for the document. @example("document.amount.units()") ## OpensearchSchemaObjectMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaObjectMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-object-mapping-type) * --- * ``properties`` - [`[OpensearchSchemaMappingsInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-mappings-input) * ## OpensearchSchemaStringMappingInput #### Input Fields --- * ``type`` - [`OpensearchSchemaStringMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-string-mapping-type) * --- * ``celExpression`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression to index for the document. _Example:_ ``"document.description"`` --- * ``fields`` - [`[OpensearchSchemaMultiFieldsInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-multi-fields-input) * Provide multi-field mappings for this field. ## OpensearchSchemaStringMultiFieldInput #### Input Fields --- * ``type`` - [`OpensearchSchemaStringMappingType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#opensearch-schema-string-mapping-type) * ## ParamDefinitionInput Define a parameter that can be used when posting transactions using this tran code. #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the parameter. This is how values passed are accessed. For example, a parameter with name `fromAccount` can be accessed in the `accountId` field of an TranCodeEntryInput with `params.fromAccount`. --- * ``type`` - [`ParamDataType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#param-data-type) * Data type for the parameter. _Default:_ ``STRING`` --- * ``default`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Default value for the parameter. If not provided, the parameter is consider a 'required' parameter, and a value must be provided when posting a transaction. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Describe the purpose of this parameter. Help an engineer out. --- * ``example`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Example value used for type-checking CEL expressions at tran code creation time. Does NOT provide a runtime default — use `default` for that. ## PartitionKeyInput Specify a named expression to define a partition key. #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Identifier for this partition key. Should be a short, human-readable name. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression which resolves to the value that is to be used for the partition key. Within the expression, the `document` object represents the record. To access a field on the document, use `document.`. --- * ``type`` - [`IndexDataType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-data-type) * Optionally provide explicit type for value. Useful for metadata values which may be list of monomorphic types. _Example:_ ``"type: STRING"`` ## PeriodRange Closed-closed period range `[gte, lte]` used by the `range` effective variant. #### Input Fields --- * ``lte`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``gte`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Periods Half-open enumeration of periods `[gte, lt)` used by the `periods` effective variant. `gte` is inclusive, `lt` is exclusive, and `lt` must be strictly greater than `gte`. #### Input Fields --- * ``gte`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``lt`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``accumulate`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, each `effectiveBalances` entry is the cumulative balance through the end of its period and the top-level balance is the closing cumulative just before `lt`. When `false` (default), each entry is that period's own activity and the top-level balance is the sum across the range. _Default:_ ``false`` ## PolicyInput #### Input Fields --- * ``effect`` - [`PolicyEffect!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#policy-effect) * Whether this Policy is an `ALLOW` or `DENY`. --- * ``actions`` - [`[PolicyAction]!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#policy-action) * The set of actions to allow or deny. --- * ``resources`` - [`[String]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The resources to allow or deny. In the format `.` The following namespaces exist: - `financial` - `tenancy` - `public` - `system` As do the following resources in the financial namespace: - `Account` - `AccountSet` - `AccountSetMember` - `Transaction` - `Entry` - `Balance` - `TranCode` - `Journal` You can use `*` to wildcard as well. --- * ``assertions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * A map of expressions to evaluate this policy with. ## RestoreInput #### Input Fields --- * ``from_region`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The region in the current tenant to restore from. --- * ``to_region`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The region in the target `tenant` to restore to. --- * ``tenant`` - [`CreateTenantInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#create-tenant-input) * The target tenant to create for restoration. --- * ``excludeTables`` - [`[ExcludeTableEnum]`](https://www.twisp.com/docs/reference/graphql/types/enum.md#exclude-table-enum) * List of tables to exclude from restoration. --- * ``exportTime`` - [`Timestamp`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp, up to 35 days in the past, to indicate from what time to export. --- * ``includeFileGlobs`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * List of glob patterns for files to include in restoration. By default no files are restored. Must supply patterns to restore files. Example: ["*.json"] includes all top level json files. ## SearchFilter SearchFilter supports Opensearch Query DSL under the "query" key See https://opensearch.org/docs/latest/query-dsl/ for more information on how to construct these queries. #### Input Fields --- * ``index`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The `name` of the search index to use. --- * ``query`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The Opensearch DSL query to use. --- * ``sort`` - [`[JSON]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The open search DSL sort to use. ## TempCredentials #### Input Fields --- * ``accessKeyId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``secretAccessKey`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``sessionToken`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## TranCodeEntryInput Defines the values for the entries written when transactions are posted with this tran code. #### Input Fields --- * ``accountId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Account ID for an entry written when this tran code is invoked. Expression must resolve to a UUID type. --- * ``units`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Units of currency for an entry written when this tran code is invoked. Expression must resolve to a Decimal type. --- * ``currency`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Currency used for an entry written when this tran code is invoked. Expression must resolve to a CurrencyCode type. --- * ``direction`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Direction for an entry written when this tran code is invoked. Expression must resolve to a DebitOrCredit enum type. --- * ``entryType`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Entry type for an entry written when this tran code is invoked. If omitted, defaults to `tranCode.code` with `_CR` or `_DR` appended depending on entry `direction`. Expression must resolve to a String type. --- * ``layer`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Layer for an entry written when this tran code is invoked. If omitted, defaults to `SETTLED` layer. Expression must resolve to a Layer enum type. --- * ``description`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Description for an entry written when this tran code is invoked." Expression must resolve to a String type. --- * ``metadata`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Metadata for the entry posted with this tran code. Expression must resolve to a JSON type. _Example:_ ``"{ 'x': 1, 'y': { 'z': 2 }}"`` --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression that indicates if this entry should be written. _Example:_ ``"params.amount > 0"`` ## TranCodeFilterInput Filter conditions to apply to a tran code query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``tranCodeId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `tranCodeId` field. Required when using index `TranCodeIndex.TRAN_CODE_ID`. --- * ``code`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `code` field. Only available when using index `TranCodeIndex.CODE`. --- * ``status`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `status` field. Only available when using index `TranCodeIndex.STATUS`. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `TranCodeIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `TranCodeIndex.SEARCH`. ## TranCodeIndexInput Specify the pre-defined TranCodeIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`TranCodeIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#tran-code-index) * Indexes for querying TranCodes. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## TranCodeInput Fields to create a new TranCode. #### Input Fields --- * ``tranCodeId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Internal UUID for the transaction code record. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The tran code represented as a unique string identifier. _Example:_ ``'ACH_CREDIT'`` --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Explanation of what this tran code represents and how it should be used. This provides documentation for the tran code. --- * ``params`` - [`[ParamDefinitionInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#param-definition-input) * Define the parameters that can be used when posting transactions using this tran code. --- * ``transaction`` - [`TranCodeTransactionInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-transaction-input) * Define the values for the transaction posted when this tran code is invoked. --- * ``entries`` - [`[TranCodeEntryInput!]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-entry-input) * Define the values of entries written when transactions are posted with this tran code. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this tran code. --- * ``vars`` - [`ExpressionNestedMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-nested-map) * Calculation area evaluated and injected as `vars` for transaction and entry evaluation. --- * ``assertions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Named boolean CEL expressions that must all evaluate to true when posting a transaction. Evaluated after params and vars are resolved. Failures return BadRequest. --- * ``workflow`` - [`TranCodeWorkflowInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-workflow-input) * Workflow execution to trigger when transactions are posted with this tran code. ## TranCodeTransactionInput Define the values for the transaction posted when this tran code is invoked. #### Input Fields --- * ``effective`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Effective date for the transaction posted with this tran code. If ommitted, defaults to `date.Today()`. Expression must be a valid ISO 8601 formatted date. @example("date('2022-12-23')") --- * ``journalId`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Journal ID for the transaction posted with this tran code. If omitted, the default journal will be used. Expression must resolve to a UUID type. @example("uuid('b28f5684-0834-4292-8016-d2f2fb0367a9')") --- * ``correlationId`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Correlation ID for the transaction posted with this tran code. Expression must resolve to a String type. _Example:_ ``"'5a028997'"`` --- * ``externalId`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * External ID for the transaction posted with this tran code. Expression must resolve to a String type. _Example:_ ``"'45415819'"`` --- * ``description`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Description for the transaction posted with this tran code. Expression must resolve to a String type. @example("'TX for ' + string(params.amount)") --- * ``metadata`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Metadata for the transaction posted with this tran code. Expression must resolve to a JSON type. _Example:_ ``"{ 'x': 1, 'y': { 'z': 2 }}"`` ## TranCodeUpdateInput TranCode fields to update. #### Input Fields --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Explanation of what this tran code represents and how it should be used. This provides documentation for the tran code. --- * ``params`` - [`[ParamDefinitionInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#param-definition-input) * Define the parameters that can be used when posting transactions using this tran code. Replaces existing parameters definition. --- * ``transaction`` - [`TranCodeTransactionInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-transaction-input) * Define values for transaction posted when this tran code is invoked. Replaces existing transaction definition. --- * ``entries`` - [`[TranCodeEntryInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-entry-input) * Define the values of entries written when transactions are posted with this tran code. Replaces existing entry definition. --- * ``status`` - [`Status`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Operational status of the tran code. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this tran code. --- * ``vars`` - [`ExpressionNestedMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-nested-map) * Variables for computation. --- * ``assertions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Named boolean CEL expressions that must all evaluate to true when posting a transaction. Evaluated after params and vars are resolved. Failures return BadRequest. --- * ``workflow`` - [`TranCodeWorkflowInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#tran-code-workflow-input) * Workflow execution to trigger when transactions are posted with this tran code. ## TranCodeWorkflowInput Input for workflow execution in tran code definition. #### Input Fields --- * ``workflowId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression for workflow ID. --- * ``executionId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression for execution ID. --- * ``task`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression for task name. --- * ``params`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * CEL expressions for workflow params. ## TransactionExceptionInput #### Input Fields --- * ``type`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable code that describes the type of exception. _Example:_ ``"FRAUD"`` --- * ``message`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable message that gives contextual detail about why this exception has occurred. _Example:_ ``"fraud system indicated 95% chance of fraud"`` --- * ``detail`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Arbitrary structured data about this particular exception. ## TransactionFilterInput Filter conditions to apply to a transaction query. Filters are only applied if the field is used by the specified index. #### Input Fields --- * ``journalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Specify the Journal to use with `eq`. If omitted, the default journal will be used. --- * ``transactionId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `transactionId` field. Required when using index `TransactionIndex.TRANSACTION_ID`. --- * ``correlationId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `correlationId` field. Required when using index `TransactionIndex.CORRELATION_ID`. --- * ``externalId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `externalId` field. Required when using index `TransactionIndex.EXTERNAL_ID`. --- * ``group`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `group` field. Required when using index `TransactionIndex.GROUP`. --- * ``custom`` - [`CustomIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter) * Filter conditions for a custom index. Only available when using index `TransactionIndex.CUSTOM`. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Filter conditions for a search. Only available when using index `TransactionIndex.SEARCH`. --- * ``transactionIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Retrieve up to 100 transactions by id. ## TransactionIndexInput Specify the pre-defined TransactionIndex and sort order to use in a query. #### Input Fields --- * ``name`` - [`TransactionIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#transaction-index) * Indexes for querying Transactions. To optimize query performance and apply desired filters, choose the appropriate index. --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## TransactionInput Fields to post a new Transaction. #### Input Fields --- * ``transactionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The ID is required to ensure an idempotent transaction. --- * ``tranCode`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * String corresponding to the `code` of a TranCode to be used for this transaction. --- * ``tranCodeVersion`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Version of the tran code to use in this transaction. If not supplied, the latest version will be used. --- * ``params`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Params object specifying values for the params defined in the corresponding TranCode. --- * ``properties`` - [`TransactionPropertiesInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-properties-input) * Set various transaction properties, including changing velocity enforcement. ## TransactionPropertiesInput #### Input Fields --- * ``overrideVelocityEnforcement`` - [`VelocityEnforcementInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-enforcement-input) * Override velocity enforcement for this request. If a velocity control action will enforce at `VOID` or `REJECT`, will enforce with the action specified in this request. This is useful for force posts, where you want to disable a velocity control with an action of `WARN`. --- * ``exception`` - [`TransactionExceptionInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#transaction-exception-input) * If provided, will post transaction and immediately void. Will also create the transaction exception provided that is returned on `Transaction.exceptions`. Using this option will automatically set the `overrideVelocityEnforcement.action` to `WARN`, allowing all velocity controls to evaluate and write exceptions at WARN level. --- * ``asVoidTransaction`` - [`AsVoidTransactionInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#as-void-transaction-input) * Post this transaction as the void of another transaction. The entries created by this transaction must net to zero with the entries of the transaction identified by `voidOf`. --- * ``idempotent`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Enables idempotent transaction posting. When true, if a transaction with this ID already exists, the existing transaction and its entries are returned instead of failing with a unique constraint violation. Guarantees: - Idempotency is keyed on `transactionId` — the caller must supply a stable ID. - The tran code must match: if the existing transaction was posted with a different tran code, the request fails with `BAD_REQUEST`. - The entries produced by the tran code must match: account, amount, direction, layer, and currency are compared. A mismatch fails with `BAD_REQUEST`. NOTE: During concurrent posting you may still receive a `TRANSACTION_ERROR` code; this is a standard retryable concurrency error. --- * ``dependsOn`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Transactions this post depends on. Each id must already exist as a committed transaction; a missing dependency fails the post. Enforced at post time only; the list is not persisted on the transaction. ## TransactionUpdateInput Transaction fields to update. #### Input Fields --- * ``externalId`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows specifying a unique external ID associated with this transaction. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the transaction. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Arbitrary structured data about this transaction. ## UpdateAliasInput #### Input Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The alias to update. --- * ``accountId`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The accountId the alias resolves to. --- * ``ttlSeconds`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * How long, in seconds, servers may cache the alias resolution. Zero means the server's default cache TTL applies. ## UpdateClientInput #### Input Fields --- * ``policies`` - [`[PolicyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#policy-input) * Replaces the existing policies with this new set of policies. ## UpdateGroupInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the group, such as 'Admins' or 'DataAnalysts'. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the group's purpose, intended to provide additional context. --- * ``policy`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A set of policies to apply to this group, formatted as a JSON list that define the permissions granted to users within this group. Valid actions include `db:Insert`, `db:Update`, `db:Delete`, `db:Select` or wildcard `*` Example: ``` policy: "[{\"actions\": [\"*\"],\"effect\": \"DENY\",\"resources\":[\"*\"],\"assertions\": {\"always false\": \"1 == 0\"}}]" ``` ## UpdateLimitInput #### Input Fields --- * ``timestampSource`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Uses timestamp from the specified source for picking the balance limit. By default uses the transaction timestamp. Must resolve to a CEL `timestamp`. @example("timestamp(context.vars.transaction.?metadata.ts.orValue(context.transaction.timestamp))") --- * ``balance`` - [`[BalanceLimitInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#balance-limit-input) * ## UpdateTenantInput #### Input Fields --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A globally unique identifier representing an environment within the organization. This accountId, when combined with an AWS region, is used to calculate the database tenant. --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the tenant, used for display purposes and easier identification. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the tenant, providing additional context about its purpose or characteristics. ## UpdateUserInput #### Input Fields --- * ``groupIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * A list of unique identifiers for the groups to which the user belongs. The user's permissions are determined by the combined policies of these groups. --- * ``email`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The user's email address, which serves as a unique identifier and primary means of contact. ## UpdateVelocityControlInput #### Input Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * If set, updates name of velocity control. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * If set, updates description of velocity control. --- * ``enforcement`` - [`VelocityEnforcementInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-enforcement-input) * If set, updates the enforcement type of the velocity control. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * If set, updates the condition for the velocity control. ## UpdateVelocityLimitInput #### Input Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * If set, updates name of velocity limit. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * If set, updates description of velocity limit. --- * ``limit`` - [`UpdateLimitInput`](https://www.twisp.com/docs/reference/graphql/types/input.md#update-limit-input) * If set, updates the limit of the velocity limit. --- * ``currency`` - [`CurrencyCode`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * If set, sets the currency of the velocity limit. Cannot unset. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * If Set, sets the condition of the velocity limit. ## UsageInput #### Input Fields --- * ``start`` - [`Date!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#date) * Start date at midnight UTC. --- * ``end`` - [`Date!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#date) * End date at midnight UTC. ## VelocityControlFilterInput #### Input Fields --- * ``velocityControlId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `velocityControlId` field. Required when using index `VelocityControlIndex.VELOCITY_CONTROL_ID`. --- * ``velocityLimitId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `velocityLimitId` field. Required when using index `VelocityControlIndex.VELOCITY_RULE_ID`. --- * ``name`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `name` field. Required when using index `VelocityControlIndex.NAME`. --- * ``accountId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on attached accounts via `accountId`. Required when using index `VelocityControlIndex.ACCOUNT_ID`. ## VelocityControlIndexInput #### Input Fields --- * ``name`` - [`VelocityControlIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#velocity-control-index) * --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## VelocityControlInput #### Input Fields --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this velocity control. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name for this velocity control. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description for this velocity control. --- * ``enforcement`` - [`VelocityEnforcementInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#velocity-enforcement-input) * The type of enforcement this velocity control generates. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if this control should trigger enforcement. The `account`, `transaction` and `entry` are available for use on `context.vars`. @example("context.vars.transaction.?metadata.skipVelocityControl.orElse(false))") --- * ``velocityLimitIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Add these velocity limits to the control. ## VelocityEnforcementInput #### Input Fields --- * ``action`` - [`VelocityEnforcementAction!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#velocity-enforcement-action) * ## VelocityLimitFilterInput #### Input Fields --- * ``velocityLimitId`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `velocityLimitId` field. Required when using index `VelocityLimitIndex.VELOCITY_RULE_ID`. --- * ``name`` - [`FilterValue`](https://www.twisp.com/docs/reference/graphql/types/input.md#filter-value) * Filter on the `name` field. Required when using index `VelocityLimitIndex.NAME`. ## VelocityLimitIndexInput #### Input Fields --- * ``name`` - [`VelocityLimitIndex!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#velocity-limit-index) * --- * ``sort`` - [`SortOrder`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * `ASC` (ascending) or `DESC` (descending). ## VelocityLimitInput #### Input Fields --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this rule. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * " Human readable description of this rule. --- * ``window`` - [`[PartitionKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#partition-key-input) * Group by these values to index the calculation. The `account`, `transaction`, `tranCode` and `entry` are available for use in the window computation on `context.vars`. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if an balance entry should be written. The `account`, `transaction` and `entry` are available for use in the window computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``limit`` - [`LimitInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#limit-input) * The limit to enforce. Can supply different limits based --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * Currency this limit applies to. If set to empty string, applies limit to all currencies. --- * ``params`` - [`[ParamDefinitionInput]`](https://www.twisp.com/docs/reference/graphql/types/input.md#param-definition-input) * The parameters for `VelocityLimit.limit`. --- * ``velocityControlIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Add the limit to the velocity controls in this list. ## VelocityWindowInput #### Input Fields --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The account or set id to search for velocity. --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Limit the search to this velocity control Id. --- * ``velocityLimitId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Limit the search to this velocity limit. --- * ``window`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The window to search. If `velocityLimitId` not present, will return any limit that supports the _entire_ window. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * Return the velocity limit for this currency. _Default:_ ``"USD"`` ## ViewConfigInput #### Input Fields --- * ``enableConcurrentPosting`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. _Default:_ ``true`` ## ViewFilter Filter input for querying view entries. #### Input Fields --- * ``index`` - [`ViewIndexFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#view-index-filter) * Use the index filter for standard index queries. --- * ``search`` - [`SearchFilter`](https://www.twisp.com/docs/reference/graphql/types/input.md#search-filter) * Use the search filter for search index queries. ## ViewIndexFilter #### Input Fields --- * ``index`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the index to use. If not provided, the standard index is queried. --- * ``partition`` - [`[CustomIndexFilterValue]`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter-value) * Specify the partition of view index. --- * ``sort`` - [`[CustomIndexFilterValue]`](https://www.twisp.com/docs/reference/graphql/types/input.md#custom-index-filter-value) * Speficy the sort of the view index. ## ViewIndexInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``unique`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is unique. --- * ``partition`` - [`[PartitionKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#partition-key-input) * The partition key used for this index. --- * ``partitionShardCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Specifies the number of shards for partition write scaling. This parameter defines how many shards the partition key is automatically split into, similarly to RAID-style disk striping. Increasing this value allows the index to distribute write throughput across multiple shards while sacrificing global sort order on the partition. For instance, setting `partitionShardCount` to 4 splits each unique partition into four shards, effectively allowing 4000 writes per second for a single partition key. --- * ``sort`` - [`[IndexKeyInput]!`](https://www.twisp.com/docs/reference/graphql/types/input.md#index-key-input) * The sort key to use for supporting range queries. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. ## ViewSearchIndexInput #### Input Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. --- * ``opensearchSchema`` - [`OpensearchSchemaInput!`](https://www.twisp.com/docs/reference/graphql/types/input.md#opensearch-schema-input) * Opensearch mapping (with CEL expressions) applied to the document prior to indexing. Required. Every view search index must declare its field types explicitly so that sort, filter, and aggregation behavior is stable across index creations. ## ViewSourceInput #### Input Fields --- * ``entity`` - [`ViewEntity!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#view-entity) * Enum of source tables that can trigger view updates. --- * ``triggers`` - [`[ViewTriggerEnum!]!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#view-trigger-enum) * ## VoidTransactionPropertiesInput #### Input Fields --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``idempotent`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, makes the void operation idempotent. If the target transaction does not exist, returns null. If the target transaction is already voided, returns the existing void transaction. ## WorkflowInput Fields to execute a new workflow. #### Input Fields --- * ``workflowId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``task`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``params`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- # Interface Types Interface types define a set of fields that other object types can implement, ensuring consistency in the schema. ## Connection Connection types must contain a `pageInfo` field as well as `nodes` and `edges`. #### Fields --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## Node The generic Node interface. All first-class entities in the API implement this interface. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. See: https://graphql.org/learn/global-object-identification/ --- # Object Types Object types represent complex objects with multiple fields and can be queried for specific data. ## AbortedSummary #### Fields --- * ``count`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of aborted requests. --- * ``errors`` - [`[FailedBulkExecutionError]`](https://www.twisp.com/docs/reference/graphql/types/object.md#failed-bulk-execution-error) * Errors from the FAILED_N.json files. ## Account Accounts model all of the economic activity that your ledger provides. The chart of accounts is the basis for creating balance sheets, P&L reports, and for understanding the balances for the customer and business entities your business services. Accounts can be organized into sets with the AccountSet type. Hierarchical tree structures which roll up balances across many accounts can be modeled by nesting sets within other sets. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `ac:` where `key` is `base64(json({ 1: accountId }))`. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the account. --- * ``externalId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows specifying a unique external ID associated with this account. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account name. _Examples:_ ``"Bill Pay Settlement"``, ``"Courtesy Credit"`` --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Shorthand code for the account, often an abbreviated version of the account name. Example: 'ACH_RECON' for an account named 'ACH Reconciliation'. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account. --- * ``status`` - [`AccountStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-status) * Current status for the account. --- * ``normalBalanceType`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Flag indicating whether this account uses a "debit normal" or a "credit normal" balance. In double-entry accounting, accounts with a debit normal balance use the balance calculation `balance = debits - credits`. This is used for asset and expense account types. Accounts with a credit normal balance, in contrast, calculate their balance with the equation `balance = credits - debits`. This is the default type for liabilities, equity, and revenue account types. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account. --- * ``config`` - [`AccountConfig!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-config) * System config for this account. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the account was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this account. Previous versions are tracked in `history`. --- * ``balances`` - [`BalanceConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-connection) * Reference to the balances for this account. Accounts have balances across all three layers: SETTLED, PENDING, and ENCUMBRANCE. Each balance reflects the current total debits and credits for all entries in this account within the specified journal and currency. --- * ``balance`` - [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * Reference to the balance for a specific journal and currency (defaults to "USD"). --- * ``entries`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * All ledger entries associated with this account. --- * ``sets`` - [`AccountSetConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-connection) * Accounts can be organized into sets. Each account can belong to zero or multiple account sets. --- * ``history`` - [`AccountConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-connection) * History of changes to this Account record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. --- * ``velocity`` - [`[VelocityBalance]`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-balance) * --- * ``controls`` - [`ResolvedVelocityControlConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control-connection) * Set of controls attached to this account. --- * ``calculations`` - [`[Calculation!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) * Retrieve the calculations that are explicitly attached to this account. --- * ``setMembershipStatuses`` - [`[AccountSetMembershipStatus!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-membership-status) * Status of the account's in-flight account set membership changes: whether its balances are still being folded into (or out of) each set. Concurrent account sets fold a new member's balances in over a settle window; until that window settles, the set appears here as SETTLING. A set with no entry is fully settled — non-concurrent sets backfill synchronously and never appear. ## AccountConfig System configuration for an account. #### Fields --- * ``enableConcurrentPosting`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, allow concurrent posting to the account. See `BalanceType` for balance retrieval options available for concurrent-enabled accounts. Defaults to `false`. --- * ``isAccountSet`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, indicates this account is an underlying account for an account set. ## AccountConnection Connection to a list of Account nodes. Access Account nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Account]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) * Accounts model all of the economic activity that your ledger provides. The chart of accounts is the basis for creating balance sheets, P&L reports, and for understanding the balances for the customer and business entities your business services. Accounts can be organized into sets with the AccountSet type. Hierarchical tree structures which roll up balances across many accounts can be modeled by nesting sets within other sets. --- * ``edges`` - [`[AccountConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-connection-edge) * Edges represent links connecting a parent or query field to a list of Account nodes. They contain a reference to the Account node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AccountConnectionEdge Edges represent links connecting a parent or query field to a list of Account nodes. They contain a reference to the Account node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Account`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) * Reference to the Account node at this edge. ## AccountSet A set of accounts. Account sets contain _members_ which can include accounts as well as other account sets. Every account set has multiple _balances_ which represent the sum of all balances of member accounts and member account sets. Like balances for accounts, account set balances are computed for every currency used by the entries posted to accounts in a set and all of its sub-sets. Because account sets are tied to a specific journal, they only compute balances using entries posted to their journal. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `as:` where `key` is `base64(json({ 1: accountSetId }))`. --- * ``accountSetId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the set. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The journal for the set. Account sets are confined to a single journal and roll up balances for entries on their journal. Account sets can only contain other sets using the same journal. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the set. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * code for the account set. Unique value. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the account set. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this account set. --- * ``config`` - [`AccountSetConfig!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-config) * System config for this account set. --- * ``normalBalanceType`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Indicates whether this account set uses a "debit normal" or a "credit normal" balance. In double-entry accounting, a debit normal balance uses the calculation `balance = debits - credits`. A credit normal balance, in contrast, is calculated with the equation `balance = credits - debits`. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the account set was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this account set. Previous versions are tracked in `history`. --- * ``status`` - [`AccountSetStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-set-status) * Lifecycle status. `DELETED` marks a soft-deleted set (set by `deleteAccountSet`); the row and its balances persist and it is never un-deleted. --- * ``balance`` - [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * Reference to the balance for a specific currency (defaults to "USD"). --- * ``balances`` - [`BalanceConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-connection) * Reference to the balances for this account set. Each balance reflects the current sum of debits and credits for all entries on accounts in this set and all accounts in any sub-sets, on the current layer and all layers above. Because account sets are tied to a specific journal, they only compute balances using entries posted to their journal. --- * ``entries`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * All ledger entries associated with accounts in this set and in all subsets. --- * ``history`` - [`AccountSetConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-connection) * History of changes to this AccountSet record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. --- * ``members`` - [`AccountSetMemberConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-member-connection) * Eventually consistent list of all members of the account set. Sets can include other account sets. When a `memberId` `eq` filter is supplied, a strongly consistent index is used. --- * ``sets`` - [`AccountSetConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-connection) * Account sets can be organized into sets. Each account set can belong to zero or multiple account sets. --- * ``velocity`` - [`[VelocityBalance]`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-balance) * Check the velocity balance for this account set. --- * ``controls`` - [`ResolvedVelocityControlConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control-connection) * Set of controls attached to this account set. --- * ``calculations`` - [`[Calculation!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) * Retrieve the calculations that are explicitly attached to this account set. ## AccountSetConfig System configuration for an account set. #### Fields --- * ``enableConcurrentPosting`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, allow concurrent posting to the account. See `BalanceType` for balance retrieval options available for concurrent-enabled accounts. Defaults to `false`. ## AccountSetConnection Connection to a list of AccountSet nodes. Access AccountSet nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[AccountSet]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) * A set of accounts. Account sets contain _members_ which can include accounts as well as other account sets. Every account set has multiple _balances_ which represent the sum of all balances of member accounts and member account sets. Like balances for accounts, account set balances are computed for every currency used by the entries posted to accounts in a set and all of its sub-sets. Because account sets are tied to a specific journal, they only compute balances using entries posted to their journal. --- * ``edges`` - [`[AccountSetConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-connection-edge) * Edges represent links connecting a parent or query field to a list of AccountSet nodes. They contain a reference to the AccountSet node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AccountSetConnectionEdge Edges represent links connecting a parent or query field to a list of AccountSet nodes. They contain a reference to the AccountSet node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`AccountSet`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) * Reference to the AccountSet node at this edge. ## AccountSetMemberConnection Connection to a list of AccountSetMember nodes. Access AccountSetMember nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[AccountSetMember!]!`](https://www.twisp.com/docs/reference/graphql/types/union.md#account-set-member) * Account set members can be of type Account or AccountSet. --- * ``edges`` - [`[AccountSetMemberConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set-member-connection-edge) * Edges represent links connecting a parent or query field to a list of AccountSetMember nodes. They contain a reference to the AccountSetMember node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AccountSetMemberConnectionEdge Edges represent links connecting a parent or query field to a list of AccountSetMember nodes. They contain a reference to the AccountSetMember node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`AccountSetMember`](https://www.twisp.com/docs/reference/graphql/types/union.md#account-set-member) * Reference to the AccountSetMember node at this edge. ## AccountSetMembershipStatus One account set with an in-flight membership change for an account. #### Fields --- * ``accountSetId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The account set the change applies to. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The journal the account set belongs to. --- * ``status`` - [`AccountSetMembershipState!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#account-set-membership-state) * The lifecycle state of the change. --- * ``changedAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * When the membership changed. --- * ``settleAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * When the change's window settles. ## AchAdvBatchControl #### Fields --- * ``serviceClassCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryAddendaCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryHash`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalDebitEntryDollarAmount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalCreditEntryDollarAmount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``achOperatorData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``batchNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchAdvEntryDetail #### Fields --- * ``transactionCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``rdfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``checkDigit`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dfiAccountNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``amount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``adviceRoutingNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``fileIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``achOperatorData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``individualName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``discretionaryData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaRecordIndicator`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``achOperatorRoutingNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``julianDay`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``sequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``addenda99`` - [`Addenda99`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda99) * ## AchAdvFileControl #### Fields --- * ``batchCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``blockCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryAddendaCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryHash`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalDebitEntryDollarAmountInFile`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalCreditEntryDollarAmountInFile`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchBatch #### Fields --- * ``header`` - [`AchBatchHeader`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-batch-header) * --- * ``control`` - [`AchBatchControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-batch-control) * --- * ``advControl`` - [`AchAdvBatchControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-adv-batch-control) * --- * ``offset`` - [`AchOffset`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-offset) * ## AchBatchControl #### Fields --- * ``serviceClassCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryAddendaCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryHash`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalDebitEntryDollarAmount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalCreditEntryDollarAmount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``companyIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``messageAuthenticationCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``batchNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchBatchHeader #### Fields --- * ``serviceClassCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``companyName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``companyDiscretionaryData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``companyIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``standardEntryClassCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``companyEntryDescription`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``companyDescriptiveDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``effectiveEntryDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``settlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorStatusCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``odfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``batchNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchConfiguration #### Fields --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this configuration. --- * ``endpointId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Endpoint to use for decisioning this ACH file. Absent on auto-pending configurations that have no webhook endpoint. --- * ``settlementAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Settlement Account. --- * ``exceptionAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an exception occurs, such as a Velocity Control or Account in a locked state. Funds in this account will be returned. --- * ``suspenseAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account to post to when an account is not found. Funds in this account will be returned. --- * ``feeAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ACH Fee Account. Absent on RDFI-only configurations that have no fee account. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to post settlements into. --- * ``odfiHeaderConfiguration`` - [`AchOdfiHeaderConfiguration!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-odfi-header-configuration) * ACH Processor immediate destination/origin configuration. --- * ``timeZone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``direction`` - [`AchConfigurationDirection!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-configuration-direction) * The direction of ACH files this configuration processes. --- * ``autoPending`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When true, RDFI entries skip the create webhook and are automatically posted as PENDING to `pendingAccountId`, awaiting manual settlement or return. --- * ``pendingAccountId`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account auto-pending entries are posted to. --- * ``traceNumberConfiguration`` - [`AchTraceNumberConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-trace-number-configuration) * Reserved range for Twisp-generated trace numbers, when configured. --- * ``fileModifierConfiguration`` - [`AchFileModifierConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-modifier-configuration) * File ID modifier configuration, when configured: the reserved range Twisp generates from, or whether the caller supplies each modifier. --- * ``offsetConfiguration`` - [`AchOffsetConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-offset-configuration) * Offset configuration for balanced origination files, when configured. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchConfigurationConnection #### Fields --- * ``nodes`` - [`[AchConfiguration]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) * --- * ``edges`` - [`[AchConfigurationConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AchConfigurationConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`AchConfiguration`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-configuration) * ## AchEntryDetail #### Fields --- * ``transactionCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``rdfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``checkDigit`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dfiAccountNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``amount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``identificationNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``individualName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``discretionaryData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaRecordIndicator`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addenda02`` - [`Addenda02`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda02) * --- * ``addenda05`` - [`[Addenda05]`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda05) * --- * ``addenda98`` - [`Addenda98`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda98) * --- * ``addenda98Refused`` - [`Addenda98Refused`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda98refused) * --- * ``addenda99`` - [`Addenda99`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda99) * --- * ``addenda99Contested`` - [`Addenda99Contested`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda99contested) * --- * ``addenda99Dishonored`` - [`Addenda99Dishonored`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda99dishonored) * ## AchFile #### Fields --- * ``header`` - [`AchFileHeader!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-header) * --- * ``control`` - [`AchFileControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-control) * --- * ``advControl`` - [`AchAdvFileControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-adv-file-control) * ## AchFileControl #### Fields --- * ``batchCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``blockCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryAddendaCount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryHash`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalDebitEntryDollarAmountInFile`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``totalCreditEntryDollarAmountInFile`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchFileHeader #### Fields --- * ``priorityCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateDestination`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOrigin`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``fileCreationDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``fileCreationTime`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``fileIdModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``recordSize`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``blockingFactor`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``formatCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateDestinationName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOriginName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``referenceCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## AchFileInfo #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `afi:` where `key` is `base64(json({ 1: fileId }))`. --- * ``fileId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier derived from fileKey to indentify a particular file being processed. --- * ``fileKey`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The file key being processed. --- * ``fileVersion`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * TBD --- * ``fileDate`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * File date from header of ACH file. --- * ``fileModifier`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * File modifier from header of ACH file. --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The ACH configuration id used to process this file. --- * ``configVersion`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The version number of the configuration used to process this file. --- * ``fileType`` - [`AchFileType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-type) * The type of file being processed. --- * ``processingStatus`` - [`AchFileProcessingStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-file-processing-status) * The last reported processing status of this file. --- * ``processingDetail`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The last string message of the processing detail of this file. --- * ``processingStatistics`` - [`AchProcessingStatistics!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-processing-statistics) * Stats about the items in process for this file. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this file process. --- * ``hasExceptions`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether one or more entries in this file were posted to an exception account. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when this file info was created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of the last modification to this file info. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this `FileInfo`. Previous versions are tracked in `history`. --- * ``history`` - [`AchFileInfoConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info-connection) * History of changes to this ACH file info. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. --- * ``records`` - [`FileRecordConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#file-record-connection) * Returns the records associated with this file. ## AchFileInfoConnection Connection to a list of ACH file nodes. Access Account nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[AchFileInfo]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info) * --- * ``edges`` - [`[AchFileInfoConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info-connection-edge) * Edges represent links connecting a parent or query field to a list of ACH file nodes. They contain a reference to the ACH file node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AchFileInfoConnectionEdge Edges represent links connecting a parent or query field to a list of ACH file nodes. They contain a reference to the ACH file node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`AchFileInfo`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file-info) * Reference to the Account node at this edge. ## AchFileModifierConfiguration #### Fields --- * ``startFileIdModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Inclusive first file ID modifier Twisp assigns each day. Absent when the caller supplies the modifier. --- * ``endFileIdModifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Inclusive last file ID modifier Twisp assigns each day. Absent when the caller supplies the modifier. --- * ``userSupplied`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether the caller assigns the file ID modifier on each generated file. ## AchGeneratedFile #### Fields --- * ``fileKey`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The key where file is stored, if generated. --- * ``generated`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates a file was generated or not. ## AchIatBatch #### Fields --- * ``header`` - [`AchIatBatchHeader`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-iat-batch-header) * --- * ``control`` - [`AchBatchControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-batch-control) * ## AchIatBatchHeader #### Fields --- * ``serviceClassCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``iatIndicator`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignExchangeIndicator`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignExchangeReferenceIndicator`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``foreignExchangeReference`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``isoDestinationCountryCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``standardEntryClassCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``companyEntryDescription`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``isoOriginatingCurrencyCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``isoDestinationCurrencyCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``effectiveEntryDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``settlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorStatusCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``odfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``batchNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## AchIatEntryDetail #### Fields --- * ``transactionCode`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``rdfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``checkDigit`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaRecords`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``amount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``dfiAccountNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``ofacScreeningIndicator`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``secondaryOfacScreeningIndicator`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaRecordIndicator`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addenda10`` - [`Addenda10`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda10) * --- * ``addenda11`` - [`Addenda11`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda11) * --- * ``addenda12`` - [`Addenda12`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda12) * --- * ``addenda13`` - [`Addenda13`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda13) * --- * ``addenda14`` - [`Addenda14`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda14) * --- * ``addenda15`` - [`Addenda15`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda15) * --- * ``addenda16`` - [`Addenda16`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda16) * --- * ``addenda17`` - [`[Addenda17]`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda17) * --- * ``addenda18`` - [`[Addenda18]`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda18) * --- * ``addenda98`` - [`Addenda98`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda98) * --- * ``addenda99`` - [`Addenda99`](https://www.twisp.com/docs/reference/graphql/types/object.md#addenda99) * ## AchOdfiHeaderConfiguration #### Fields --- * ``immediateDestination`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateDestinationName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOrigin`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``immediateOriginName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## AchOffset #### Fields --- * ``routingNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``accountNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``accountType`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## AchOffsetConfiguration #### Fields --- * ``routingNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Routing number of the account offset entries are drawn on. Absent when the configuration's `immediateOrigin` is used. --- * ``accountNumber`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Account number offset entries are drawn on. --- * ``accountType`` - [`AchOffsetAccountType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#ach-offset-account-type) * Type of the offset account. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Discretionary data for offset entries. --- * ``enableBalancedReturnNOCs`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether generated return and NOC files are balanced as well. ## AchProcessedFile #### Fields --- * ``fileId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## AchProcessingStatistics #### Fields --- * ``numEntriesUnprocessed`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The number of entries remaining that need to respond to create webhook. --- * ``totalCreditAmount`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Total credit amount in the file. --- * ``totalDebitAmount`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Total debit amount in the file. ## AchTraceNumberConfiguration #### Fields --- * ``minTraceNumber`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Minimum trace number Twisp will generate. --- * ``maxTraceNumber`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Maximum trace number Twisp will generate. ## AchWorkflowTrace Audit trail that links workflow executions to specific ACH entries. Provides complete traceability from business logic execution to ACH network transactions enabling returns processing, reconciliation, and compliance auditing. #### Fields --- * ``workflowId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the workflow template that processed this ACH entry. Links to the business logic used for processing this transaction. --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the specific execution instance of the workflow. Each workflow run gets a unique execution ID for audit and debugging purposes. --- * ``fileId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the ACH file containing this entry. References the source file that was processed. --- * ``recordId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the specific ACH entry detail record. Links to the individual record within the ACH file. --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the ACH configuration used to process this entry. References the processing rules, accounts, and ODFI settings applied. --- * ``traceNumber`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * ACH trace number from the entry detail record (15 digits). Required for ACH returns, corrections, and reconciliation with the banking network. Format: ODFI routing number (8 digits) + sequence number (7 digits). _Example:_ ``"123456780001234"`` ## Addenda02 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``referenceInformationOne`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``referenceInformationTwo`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``terminalIdentificationCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``transactionSerialNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``transactionDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``authorizationCodeOrExpireDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``terminalLocation`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``terminalCity`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``terminalState`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Addenda05 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``paymentRelatedInformation`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``sequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda10 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``transactionTypeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignPaymentAmount`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``foreignTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda11 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorStreetAddress`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda12 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorCityStateProvince`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originatorCountryPostalCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda13 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiIdNumberQualifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``odfiBranchCountryCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda14 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``rdfiName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``rdfiIdNumberQualifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``rdfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``rdfiBranchCountryCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda15 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``receiverIdNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``receiverStreetAddress`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda16 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``receiverCityStateProvince`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``receiverCountryPostalCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda17 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``paymentRelatedInformation`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``sequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda18 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignCorrespondentBankName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignCorrespondentBankIdNumberQualifier`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignCorrespondentBankIdNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``foreignCorrespondentBankBranchCountryCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``sequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryDetailSequenceNumber`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Addenda98 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``changeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalTrace`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalDfi`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``correctedData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``iatCorrectedData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Addenda98Refused #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``refusedChangeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalTrace`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalDfi`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``correctedData`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``changeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceSequenceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Addenda99 #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalTrace`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dateOfDeath`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalDfi`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaInformation`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Addenda99Contested #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``contestedReturnCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalEntryTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dateOriginalEntryReturned`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalReceivingDfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalSettlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnSettlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnReasonCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dishonoredReturnTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dishonoredReturnSettlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dishonoredReturnReasonCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Addenda99Dishonored #### Fields --- * ``typeCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dishonoredReturnReasonCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalEntryTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``originalReceivingDfiIdentification`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnTraceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnSettlementDate`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``returnReasonCode`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``addendaInformation`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``traceNumber`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## Alias An Alias maps a stable, human-friendly identifier to a tenant accountId within a region. Requests may pass `alias/` followed by the alias name via `x-twisp-account-id`. The server resolves it to the accountId the alias points to. An alias exists only in the region it was created in, its name is first-come-first-served within that region, and only the organization that created it can modify or delete it. #### Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The raw alias name, without the `alias/` account-ID qualifier. --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The accountId the alias resolves to. --- * ``organizationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the organization that owns the alias. --- * ``region`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The region the alias exists in. --- * ``ttlSeconds`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * How long, in seconds, servers may cache the alias resolution. Zero means the server's default cache TTL applies. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this alias. Updates will increment the version. ## AliasConnection Connection to a list of Alias nodes. Access Alias nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Alias]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias) * An Alias maps a stable, human-friendly identifier to a tenant accountId within a region. Requests may pass `alias/` followed by the alias name via `x-twisp-account-id`. The server resolves it to the accountId the alias points to. An alias exists only in the region it was created in, its name is first-come-first-served within that region, and only the organization that created it can modify or delete it. --- * ``edges`` - [`[AliasConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias-connection-edge) * Edges represent links connecting a parent or query field to a list of Alias nodes. They contain a reference to the Alias node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## AliasConnectionEdge Edges represent links connecting a parent or query field to a list of Alias nodes. They contain a reference to the Alias node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Alias`](https://www.twisp.com/docs/reference/graphql/types/object.md#alias) * Reference to the Alias node at this edge. ## AttachedCalculation #### Fields --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``account`` - [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) * Accounts model all of the economic activity that your ledger provides. The chart of accounts is the basis for creating balance sheets, P&L reports, and for understanding the balances for the customer and business entities your business services. Accounts can be organized into sets with the AccountSet type. Hierarchical tree structures which roll up balances across many accounts can be modeled by nesting sets within other sets. --- * ``calculation`` - [`Calculation!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) * ## Balance Balances are auto-calculated sums of the entries for a given account. Every balance record maintains a `drBalance` for entries on the debit side of the ledger and a `crBalance` for credit entries. Additionally, every account has a `normalBalance`, which is equal to `crBalance - drBalance` for credit normal accounts, and `drBalance - crBalance` for debit normal accounts. Each account can have balances across all three layers: SETTLED, PENDING, and ENCUMBRANCE. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `ba:` where `key` is `base64(json({ 1: accountId, 2: journalId, 3: currency, 4: calculationId, 5: dimension }))` The journalId and currency are optional and will use the default values if they are missing. The calculationId and dimension are included for calculation-specific balances. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the journal within which the balance is calculated. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the account for which the balance is calculated. --- * ``entryId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the most recent entry used to calculate the balance. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * The currency of the balance amounts. Balances represent the sum of entries using the same currency. Multi-currency ledgers will therefore have different balances for each currency. --- * ``settled`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the settled layer. --- * ``pending`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the pending layer. --- * ``encumbrance`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the encumbrance layer. --- * ``dimensions`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The dimensions that make up this balance calculation --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The calculationId of this balance --- * ``available`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts available by combining the provided layer with all layers above. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the balance was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this balance. Previous versions are tracked in `history`. --- * ``effectiveBalances`` - [`[EffectivePeriod]`](https://www.twisp.com/docs/reference/graphql/types/object.md#effective-period) * Per-period entries when queried with `effective.cumulative`, `effective.range`, or `effective.periods`. Each entry's `effective` field identifies the period it covers. Contents depend on the `Effective` variant used: - `cumulative`: the underlying year/month/day buckets that the aggregate was summed from. - `range`: one entry per bucket in `[gte, lte]`, each holding that period's activity. - `periods`: one entry per period in the half-open `[gte, lt)` interval in chronological order. With `accumulate: true`, each entry is the cumulative balance through the end of that period; with `accumulate: false` (default), each entry is that period's own activity. --- * ``account`` - [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) * Reference to the balance's account. --- * ``entry`` - [`Entry!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) * Reference to the most recent entry used to calculate the balance. --- * ``entries`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * All ledger entries for this balance. --- * ``journal`` - [`Journal!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) * Reference to the balance's journal. --- * ``history`` - [`BalanceConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-connection) * History of changes to this Balance record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. ## BalanceAmount #### Fields --- * ``drBalance`` - [`Money!`](https://www.twisp.com/docs/reference/graphql/types/object.md#money) * Sum of all amounts for entries on the DEBIT side of the ledger. --- * ``crBalance`` - [`Money!`](https://www.twisp.com/docs/reference/graphql/types/object.md#money) * Sum of all amounts for entries on the CREDIT side of the ledger. --- * ``normalBalance`` - [`Money!`](https://www.twisp.com/docs/reference/graphql/types/object.md#money) * The "normal balance" for an account is different for credit normal and debit normal accounts. For credit normal accounts, the normal balance is equal to `crBalance - drBalance`. For debit normal accounts, the normal balance is the reverse: `drBalance - crBalance`. --- * ``entryId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the most recent entry used to calculate the balance on this layer. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change of balance on this layer. ## BalanceConnection Connection to a list of Balance nodes. Access Balance nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Balance]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * Balances are auto-calculated sums of the entries for a given account. Every balance record maintains a `drBalance` for entries on the debit side of the ledger and a `crBalance` for credit entries. Additionally, every account has a `normalBalance`, which is equal to `crBalance - drBalance` for credit normal accounts, and `drBalance - crBalance` for debit normal accounts. Each account can have balances across all three layers: SETTLED, PENDING, and ENCUMBRANCE. --- * ``edges`` - [`[BalanceConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-connection-edge) * Edges represent links connecting a parent or query field to a list of Balance nodes. They contain a reference to the Balance node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## BalanceConnectionEdge Edges represent links connecting a parent or query field to a list of Balance nodes. They contain a reference to the Balance node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * Reference to the Balance node at this edge. ## BalanceLimit #### Fields --- * ``layer`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The layer this balance limit is enforced at. --- * ``amount`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The maximum amount at this layer that can be spent. --- * ``NormalBalanceType`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The direction this balance enforces on. --- * ``start`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The timestamp at which this balance limit begins to be effective. --- * ``end`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The timestamp at which this balance limit ceases to be effective. ## BatchExecuteStatementOutput #### Fields --- * ``createdAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``database`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dbUser`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``id`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## BulkQueryExecution #### Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this bulk execution. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Key to variables file to use. --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique Identifier for this execution of a bulk query. --- * ``query`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Parameterized GraphQL query string to execute. --- * ``status`` - [`BulkQueryExecutionStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#bulk-query-execution-status) * Status of this execution. --- * ``resultKeys`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Set when `status` is `COMPLETE`, lists the keys to download the results files. --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * If `status` in error, a diagnostic message for the cause of the error. --- * ``summary`` - [`BulkQueryExecutionSummary`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution-summary) * Summary of the bulk query execution. Populated on COMPLETE or ERROR. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. ## BulkQueryExecutionConnection Connection to a list of BulkQueryExecution nodes. Access BulkQueryExecution nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[BulkQueryExecution]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution) * --- * ``edges`` - [`[BulkQueryExecutionConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution-connection-edge) * Edges represent links connecting a parent or query field to a list of BulkQueryExecution nodes. They contain a reference to the BulkQueryExecution node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## BulkQueryExecutionConnectionEdge Edges represent links connecting a parent or query field to a list of BulkQueryExecution nodes. They contain a reference to the BulkQueryExecution node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`BulkQueryExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#bulk-query-execution) * Reference to the BulkQueryExecution node at this edge. ## BulkQueryExecutionSummary #### Fields --- * ``total`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * total number of requests in this execution. --- * ``executed`` - [`ExecutedSummary!`](https://www.twisp.com/docs/reference/graphql/types/object.md#executed-summary) * Summary of executed requests. --- * ``aborted`` - [`AbortedSummary!`](https://www.twisp.com/docs/reference/graphql/types/object.md#aborted-summary) * Summary of aborted requests due to aborted execution. The requests in FAILED_N.json _may not_ have been executed. The requests in PENDING_N.json _were not_ executed. ## Calculation #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this calculation. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique shorthand code for this calculation. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this calculation. --- * ``scope`` - [`CalculationScope!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#calculation-scope) * The calculation scope of this calculation. --- * ``dimensions`` - [`[PartitionKey]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * Group by these values to index the calculation. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Boolean expression indicating if a balance entry should be written. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the balance calculation was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this calculation. Previous versions are tracked in `history`. --- * ``backfillStatus`` - [`CalculationBackfillStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#calculation-backfill-status) * The current backfill status. --- * ``status`` - [`CalculationStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#calculation-status) * The status of this calculation. --- * ``config`` - [`CalculationConfig`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation-config) * Config options for this calculation. ## CalculationConfig #### Fields --- * ``enableEffectiveBalances`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether this calculation has effective date child calculations. --- * ``effectiveDateSource`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression used as the base for effective date dimensions, if set. ## CalculationConnection Connection to a list of Calculation nodes. Access Calculation nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Calculation]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) * --- * ``edges`` - [`[CalculationConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## CalculationConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Calculation`](https://www.twisp.com/docs/reference/graphql/types/object.md#calculation) * Reference to the Calculation node at this edge. ## CancelBulkQueryExecutionResult Result of a cancelExecution request. #### Fields --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The execution ID that was requested to be cancelled. --- * ``stopping`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether a stop request was successfully sent to the execution. ## CancelStatementOutput #### Fields --- * ``status`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. ## Client #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `cl:` where `key` is the `base64(json({ 1: principal }))` --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Principal that this client applies to. If you're supplying your own OIDC this will be the `iss` claim on your JWT. If using Twisp IAM/OIDC token exchange, this will be the IAM principal you signed with, typically a role ARN. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique name of the client. --- * ``policies`` - [`[Policy]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#policy) * The policies to evaluate. ## ClientConnection Connection to a list of Client nodes. Access Client nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Client]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) * --- * ``edges`` - [`[ClientConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#client-connection-edge) * Edges represent links connecting a parent or query field to a list of Client nodes. They contain a reference to the Client node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ClientConnectionEdge Edges represent links connecting a parent or query field to a list of Client nodes. They contain a reference to the Client node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Client`](https://www.twisp.com/docs/reference/graphql/types/object.md#client) * Reference to the Client node at this edge. ## DescribeStatementOutput #### Fields --- * ``createdAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``updatedAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``duration`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``resultRows`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``resultSize`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``status`` - [`SqlStatementStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sql-statement-status) * --- * ``hasResultSet`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``database`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dbUser`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``id`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``queryString`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``workgroupName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``subStatements`` - [`[DescribeStatementOutput_SubStatement]`](https://www.twisp.com/docs/reference/graphql/types/object.md#describe-statement-output-sub-statement) * ## DescribeStatementOutput_SubStatement #### Fields --- * ``createdAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``updatedAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``duration`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``resultRows`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``resultSize`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``status`` - [`SqlStatementStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sql-statement-status) * --- * ``hasResultSet`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``id`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``queryString`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## DescribeTableOutput #### Fields --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``columnList`` - [`[SQLColumnMetadata]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlcolumn-metadata) * ## DocumentElement #### Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Alias for this element. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * The CEL expression for the value of this document element. --- * ``type`` - [`CelType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#cel-type) * The type this document element resolves to. --- * ``listOfType`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * If `true` resolves the type as a `[type]` ## Download #### Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of file. e.g. `path/to/file.json` --- * ``downloadURL`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Presigned URL for downloading the file. --- * ``downloadURLExpiration`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when presigned url expires. --- * ``downloadHeaders`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Headers to include in the upload request. --- * ``contentType`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * `Content-Type` of the file. ## EffectivePeriod A single per-period balance entry returned via `Balance.effectiveBalances` when the parent balance was queried with `effective.range` or `effective.periods`. For `range` queries, each entry represents the activity for that one period. For `periods` queries with `accumulate: false` (default), each entry is the period's activity; with `accumulate: true`, each entry is the cumulative balance through the end of that period. #### Fields --- * ``effective`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The period this entry covers. The format reflects the granularity inferred from the originating query: `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`. --- * ``settled`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the settled layer for this period. --- * ``pending`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the pending layer for this period. --- * ``encumbrance`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts on the encumbrance layer for this period. --- * ``available`` - [`BalanceAmount!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-amount) * The balance amounts available by combining the provided layer with all layers above. --- * ``dimensions`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The dimensions of the underlying bucket calculation. --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The calculationId of the underlying bucket. ## Endpoint #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `ep:` where `key` is `base64(json({ 1: endpointId }))`. --- * ``endpointId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the endpoint. --- * ``status`` - [`EndpointStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-status) * Current status for the endpoint. --- * ``endpointType`` - [`EndpointType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#endpoint-type) * The type of endpoint this represents. --- * ``url`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The url for the endpoint. e.g. https://yourdomain.com/path/to/hooks --- * ``subscription`` - [`[String!]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The events this is subscribed to. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of this endpoint. --- * ``signingSecret`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The secret Twisp will use to sign payloads with via HMAC/SHA256. --- * ``filters`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying conditions for sending an event to the endpoint. Record is only sent if _all_ expressions evaluate to true, i.e. they are combined with a logical AND. Each expression must return a boolean value. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * When this endpoint was created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * When this endpoint was last updated. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version of the endpoint. ## EndpointConnection #### Fields --- * ``nodes`` - [`[Endpoint]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) * --- * ``edges`` - [`[EndpointConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## EndpointConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`Endpoint`](https://www.twisp.com/docs/reference/graphql/types/object.md#endpoint) * ## Entry An entry represents one side of a transaction in a ledger. In other systems, these may be called "ledger lines" or "journal entries". Entries always have an account, amount, and direction (CREDIT or DEBIT). In addition, Twisp uses the concept of "entry types" to assign every entry to a categorical type. Twisp enforces double-entry accounting, which in practice means that entries can only be entered in the context of a Transaction. Posting a transaction will create _at least 2_ ledger entries. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `en:` where `key` is `base64(json({ 1: entryId }))`. --- * ``entryId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the ledger entry. --- * ``transactionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the transaction which posted this entry. Every entry is associated with a transaction. --- * ``voidOf`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Identifier of the entry this entry voids, when this is a void entry. --- * ``voidedBy`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Identifier of the entry that voided this entry, when this entry has been voided. --- * ``accountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the account to be debited/credited. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The journal identifier of the ledger entry. --- * ``entryType`` - [`EntryType!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#entry-type) * Type code for the entry. --- * ``layer`` - [`Layer!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#layer) * The layer on which this entry is recorded (SETTLED, PENDING, or ENCUMBRANCE). --- * ``units`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * Syntactic sugar for `amount { units }`. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * Syntactic sugar for `amount { currency }`. --- * ``amount`` - [`Money!`](https://www.twisp.com/docs/reference/graphql/types/object.md#money) * Amount of the ledger entry using the currency-supported Money type. --- * ``direction`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * The side of the ledger (DEBIT or CREDIT) this entry is posted on. --- * ``sequence`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The order in which this entry was posted within the context of a transaction. This order is auto-generated at time of posting and is determined by the position of the entries posted within the transaction. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the ledger entry. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Arbitrary structured data about this entry. --- * ``parentAccountIds`` - [`[UUID]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Account sets this entry was posted to. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the entry was posted. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this entry. Previous versions are tracked in `history`. --- * ``account`` - [`Account!`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) * Reference to the account to be debited/credited. --- * ``balance`` - [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * Reference to the resulting balance from the entry. --- * ``journal`` - [`Journal!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) * Reference to the journal of the entry. --- * ``history`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * History of changes to this Entry record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. --- * ``transaction`` - [`Transaction!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) * Reference to the transaction which posted this entry. ## EntryConnection Connection to a list of Entry nodes. Access Entry nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Entry]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) * An entry represents one side of a transaction in a ledger. In other systems, these may be called "ledger lines" or "journal entries". Entries always have an account, amount, and direction (CREDIT or DEBIT). In addition, Twisp uses the concept of "entry types" to assign every entry to a categorical type. Twisp enforces double-entry accounting, which in practice means that entries can only be entered in the context of a Transaction. Posting a transaction will create _at least 2_ ledger entries. --- * ``edges`` - [`[EntryConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection-edge) * Edges represent links connecting a parent or query field to a list of Entry nodes. They contain a reference to the Entry node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## EntryConnectionEdge Edges represent links connecting a parent or query field to a list of Entry nodes. They contain a reference to the Entry node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Entry`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) * Reference to the Entry node at this edge. ## ExecuteStatementOutput #### Fields --- * ``createdAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``database`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``dbUser`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``id`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ExecuteStatementSyncOutput #### Fields --- * ``records`` - [`[SQLRecord]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlrecord) * --- * ``columnMetadata`` - [`[SQLColumnMetadata]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlcolumn-metadata) * --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``totalNumRows`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## ExecutedSummary #### Fields --- * ``count`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Number of executed requests. --- * ``status`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Of the requests executed, counts of results by status error code. Successful are "OK". If only keys are "OK" and "UNIQUE_KEY_VIOLATION" all the requests in the bulk execution succeeded or already exists. ## Export #### Fields --- * ``id`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``status`` - [`SqlStatementStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sql-statement-status) * --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## FailedBulkExecutionError #### Fields --- * ``error`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``cause`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## FileListPage #### Fields --- * ``keys`` - [`[KeyWithDownload!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#key-with-download) * --- * ``nextPageToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## FileRecord #### Fields --- * ``record`` - [`AchRecord!`](https://www.twisp.com/docs/reference/graphql/types/union.md#ach-record) * --- * ``recordId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``recordType`` - [`FileRecordType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#file-record-type) * --- * ``recordCount`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``recordPosition`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``batchCount`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``batchPosition`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryCount`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``entryPosition`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``execution`` - [`WorkflowExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) * Returns workflow execution backing this file record. ## FileRecordConnection #### Fields --- * ``nodes`` - [`[FileRecord]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#file-record) * --- * ``edges`` - [`[FileRecordConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#file-record-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## FileRecordConnectionEdge #### Fields --- * ``node`` - [`FileRecord`](https://www.twisp.com/docs/reference/graphql/types/object.md#file-record) * --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## GetStatementResultOutput #### Fields --- * ``records`` - [`[SQLRecord]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlrecord) * --- * ``columnMetadata`` - [`[SQLColumnMetadata]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlcolumn-metadata) * --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``totalNumRows`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## Group Grouping of users within an organization. Groups are used to manage access control and permissions for users. Each group can have one or more associated policies that define the allowed actions for its member users. Users can belong to multiple groups, and their permissions are determined by the combined set of policies from all their groups. #### Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the group. --- * ``organizationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The unique identifier of the organization to which the group belongs. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the group, such as 'Admins' or 'DataAnalysts'. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the group's purpose, intended to provide additional context. --- * ``policy`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A set of policies as a JSON list that define the permissions granted to users within this group. The structure of these policies matches the Policy type, but serialized as a JSON string. Example: ``` policy: "[{\"actions\": [\"*\"],\"effect\": \"DENY\",\"resources\":[\"*\"],\"assertions\": {\"always false\": \"1 == 0\"}}]" ``` --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this group. Updates will increment the version. ## GroupConnection Connection to a list of Group nodes. Access Group nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Group]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#group) * Grouping of users within an organization. Groups are used to manage access control and permissions for users. Each group can have one or more associated policies that define the allowed actions for its member users. Users can belong to multiple groups, and their permissions are determined by the combined set of policies from all their groups. --- * ``edges`` - [`[GroupConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#group-connection-edge) * Edges represent links connecting a parent or query field to a list of Group nodes. They contain a reference to the Group node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## GroupConnectionEdge Edges represent links connecting a parent or query field to a list of Group nodes. They contain a reference to the Group node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Group`](https://www.twisp.com/docs/reference/graphql/types/object.md#group) * Reference to the Group node at this edge. ## ISO8583Config #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `iso8583:config:`. --- * ``configId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this configuration. --- * ``settlementAccountId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ISO8583 Settlement Account. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal to post settlements into. --- * ``timeZone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * IANA Timezone identifier for the configuration. _Example:_ ``"America/Chicago"`` --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of this configuration. --- * ``processor`` - [`ISO8583ProcessorType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#iso8583processor-type) * Processor type for this configuration. --- * ``processorSpec`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * A moov iso8583 specification. If not passed will use either the default I2C specification (for I2C users) or the ascii87 spec. --- * ``openToBuyConfig`` - [`OpenToBuyConfig!`](https://www.twisp.com/docs/reference/graphql/types/object.md#open-to-buy-config) * Which balance to use for balance inquiry or partial authorizations. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when this configuration was created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of the last modification to this configuration. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``history`` - [`ISO8583ConfigHistoryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config-history-connection) * History of changes to this ISO8583 configuration. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. ## ISO8583ConfigConnection Connection to a list of ISO8583 config nodes. Access ISO8583 config nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[ISO8583Config]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) * --- * ``edges`` - [`[ISO8583ConfigConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config-connection-edge) * Edges represent links connecting a parent or query field to a list of ISO8583 config nodes. They contain a reference to the ISO8583 config node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ISO8583ConfigConnectionEdge Edges represent links connecting a parent or query field to a list of ISO8583 config nodes. They contain a reference to the ISO8583 config node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) * Reference to the ISO8583 config node at this edge. ## ISO8583ConfigHistoryConnection Connection to a list of ISO8583 config history nodes. Access ISO8583 config history nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[ISO8583Config]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) * --- * ``edges`` - [`[ISO8583ConfigHistoryConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config-history-connection-edge) * Edges represent links connecting a parent or query field to a list of ISO8583 config history nodes. They contain a reference to the ISO8583 config history node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ISO8583ConfigHistoryConnectionEdge Edges represent links connecting a parent or query field to a list of ISO8583 config history nodes. They contain a reference to the ISO8583 config history node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`ISO8583Config`](https://www.twisp.com/docs/reference/graphql/types/object.md#iso8583config) * Reference to the ISO8583 config history node at this edge. ## Index #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `ix:` where `key` is `base64(json({ 1: name, 2: on }))`. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``on`` - [`IndexOnEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-on-enum) * The type of record this index applies to. --- * ``viewName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the view this index is attached to. Populated only when `on: View`. --- * ``async`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is populated asynchronously. --- * ``unique`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is unique. --- * ``search`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is a search index. --- * ``historical`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is historical, i.e. created with `schema.createHistoricalIndex`. --- * ``partition`` - [`[PartitionKey]`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * For non-search indexes, the partition key used for this index. --- * ``range`` - [`[IndexKey]`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-key) * For non-search indexes, the range key to use for query/sorting. --- * ``opensearchSchema`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The Opensearch CEL expression schema to apply to the document prior to indexing. Only available on search indexes. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCateogory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. --- * ``partitionShardCount`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Specifies the number of shards for partition write scaling. This parameter defines how many shards the partition key is automatically split into, similarly to RAID-style disk striping. Increasing this value allows the index to distribute write throughput across multiple shards while sacrificing global sort order on the partition. For instance, setting `partitionShardCount` to 4 splits each unique partition into four shards, effectively allowing 4000 writes per second for a single partition key. --- * ``indexId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Twisp generated internal index identifier. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this index. --- * ``status`` - [`IndexStatus!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-status) * ## IndexConnection Connection to a list of Index nodes. Access Index nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Index]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) * --- * ``edges`` - [`[IndexConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-connection-edge) * Edges represent links connecting a parent or query field to a list of Index nodes. They contain a reference to the Index node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## IndexConnectionEdge Edges represent links connecting a parent or query field to a list of Index nodes. They contain a reference to the Index node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Index`](https://www.twisp.com/docs/reference/graphql/types/object.md#index) * Reference to the Index node at this edge. ## IndexKey A named expression used for sorting and range conditions. #### Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Identifier for this key. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression which resolves to the value that is to be sorted. Within the expression, the `document` object represents the record. --- * ``sort`` - [`SortOrder!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sort-order) * Whether the sort is in ascending or descending order. --- * ``type`` - [`IndexDataType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-data-type) * Explicit type for sort key. ## IndexStatus #### Fields --- * ``status`` - [`IndexStatusEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-status-enum) * The current state of the index. --- * ``percentageComplete`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The percentage completion of index creation/backfill. ## Journal Journals allow for the organizing of transactions within separate "books". In many cases, users only need a single journal. For this reason, Twisp always contains a default journal with code `DEFAULT`. Journals can be used for a variety of functions. For example, users may create separate journals for different currencies, or product-specific journals. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `jl:` where `key` is `base64(json({ 1: journalId }))`. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the journal. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the journal. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the journal. --- * ``status`` - [`Status!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Operational status of the journal. `ACTIVE` journals can be written to with `postTransaction`, whereas `LOCKED` journals do not allow transactions to be posted to them. --- * ``code`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional unique code for the journal. The default journal uses the code `DEFAULT`. --- * ``config`` - [`JournalConfig!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-config) * Journal specific configuration options for transactions and balances recorded in this journal. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the journal was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this journal. Previous versions are tracked in `history`. --- * ``history`` - [`JournalConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection) * History of changes to this Journal record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. ## JournalConfig System configuration for a journal. #### Fields --- * ``enableEffectiveBalances`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * When `true`, records point-in-time effective balances for all accounts in the journal. Defaults to `false`. ## JournalConnection Connection to a list of Journal nodes. Access Journal nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Journal]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) * Journals allow for the organizing of transactions within separate "books". In many cases, users only need a single journal. For this reason, Twisp always contains a default journal with code `DEFAULT`. Journals can be used for a variety of functions. For example, users may create separate journals for different currencies, or product-specific journals. --- * ``edges`` - [`[JournalConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal-connection-edge) * Edges represent links connecting a parent or query field to a list of Journal nodes. They contain a reference to the Journal node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## JournalConnectionEdge Edges represent links connecting a parent or query field to a list of Journal nodes. They contain a reference to the Journal node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Journal`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) * Reference to the Journal node at this edge. ## KVConnection #### Fields --- * ``nodes`` - [`[KVValue]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) * --- * ``edges`` - [`[KVConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvconnection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## KVConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`KVValue`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue) * ## KVValue #### Fields --- * ``namespace`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Logical grouping key for the record. --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique key within the namespace. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Optional human-readable description stored with the record. --- * ``value`` - [`Value!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#value) * Arbitrary JSON payload stored for the record. --- * ``conditions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * CEL conditions evaluated before this version of the record was written, keyed by condition name. Null / empty when no conditions were used. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Record creation timestamp. Preserved across updates. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Record last-modified timestamp. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Current record version. --- * ``history`` - [`KVConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvconnection) * Historical versions of this record, returned newest-first. ## KeyWithDownload #### Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``download`` - [`Download`](https://www.twisp.com/docs/reference/graphql/types/object.md#download) * ## Limit #### Fields --- * ``timestampSource`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A literal CEL expression to be evaluated. --- * ``balance`` - [`[BalanceLimit!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance-limit) * ## ListDatabasesOutput #### Fields --- * ``databases`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ListSchemasOutput #### Fields --- * ``schemas`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ListStatementsOutput #### Fields --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``statements`` - [`[ListStatementsOutput_Statement]`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-statements-output-statement) * ## ListStatementsOutput_Statement #### Fields --- * ``id`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``createdAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. --- * ``isBatchStatement`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``queryString`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``queryStrings`` - [`[String]`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``statementName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``status`` - [`SqlStatementStatus!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sql-statement-status) * --- * ``updatedAt`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. ## ListTablesOutput #### Fields --- * ``nextToken`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``tables`` - [`[ListTablesOutput_Table]`](https://www.twisp.com/docs/reference/graphql/types/object.md#list-tables-output-table) * ## ListTablesOutput_Table #### Fields --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``schema`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``type`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## LithicTransactionBalance #### Fields --- * ``transaction`` - [`Transaction!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) * The transaction that Twisp posted. --- * ``balance`` - [`Balance!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * The balance for the account. ## Money Money type with multi-currency support. Monetary amounts are represented as decimal units of currency. Fields which use the Money type can be converted to a symbolic representations by specifying a MoneyFormatInput on the `formatted` field. Here is an example table showing different currencies which each have their own divisions of units represented. Japanese yen (JPY) don't have a decimal minor unit, and Bahraini dinars (BHD) use 3 minor unit decimal places. The `formatted` column uses the default values for a an `en-US` locale. | Currency | Units | Formatted | |----------|----------|-----------| | USD | `289.27` | $289.27 | | BHD | `28.927` | 28.927 BD | | JPY | `28927` | ¥28927 | #### Fields --- * ``units`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * Decimal is a fixed-precision data type supporting exact representation of numeric values. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * ISO 4217 standard three-character code indicating the currency. --- * ``formatted`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## OpenToBuyConfig #### Fields --- * ``openToBuy`` - [`OpenToBuyType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#open-to-buy-type) * ## Organization The organization associated with the auth context. Organizations have many tenants, groups, and users. #### Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the organization. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the organization. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the organization. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this organization. ## PageInfo #### Fields --- * ``hasPreviousPage`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * True if there are nodes in the connection before the current page / start cursor. --- * ``hasNextPage`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * True if there are nodes in the connection after the current page / end cursor. --- * ``startCursor`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Query cursor for the first node in the current page. --- * ``endCursor`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Query cursor for the last node in the current page. ## ParamDefinition Definition of a parameter that can be used when posting transactions using this tran code. These definitions are used to validate the provided `params` in a TransactionInput to ensure that only the right data is applied to the entries created. With CEL, you can access the post-time values of these parameters inside of values in `transaction` and `entries`. #### Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name for the parameter. This is how values passed are accessed. For example, a parameter with name `fromAccount` can be accessed in the `accountId` field of an TranCodeEntryInput with `params.fromAccount`. --- * ``type`` - [`ParamDataType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#param-data-type) * Data type for the parameter. --- * ``default`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Default value for the parameter. If not provided, the parameter is consider a 'required' parameter, and a value must be provided when posting a transaction. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Describe the purpose of this parameter. Help an engineer out. --- * ``example`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Example value used for type-checking CEL expressions at tran code creation time. Does NOT provide a runtime default — use `default` for that. If set, the type-checker uses this value instead of `default` to validate expressions. ## PartitionKey A named expression defining a partition key. #### Fields --- * ``alias`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Identifier for this partition key. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression which resolves to the value that is to be used for the partition key. Within the expression, the `document` object represents the record. --- * ``type`` - [`IndexDataType`](https://www.twisp.com/docs/reference/graphql/types/enum.md#index-data-type) * Resolved type of this partition element. ## Policy #### Fields --- * ``effect`` - [`PolicyEffect!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#policy-effect) * Whether this Policy is an `ALLOW` or `DENY`. --- * ``actions`` - [`[PolicyAction]!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#policy-action) * The set of actions to allow or deny." --- * ``resources`` - [`[String]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The resources to allow or deny. --- * ``assertions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * A map of expressions to evaluate this policy with. ## PolicyAssertion #### Fields --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``value`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A literal CEL expression to be evaluated. ## ResolvedBalanceLimit #### Fields --- * ``layer`` - [`Layer!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#layer) * Layer at which this balance is balance is enforced. --- * ``amount`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * Decimal amount of the limit. --- * ``normalBalanceType`` - [`DebitOrCredit!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#debit-or-credit) * Normal balance direction of this limit. --- * ``start`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when this limit starts application. --- * ``end`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when this limit ends application. ## ResolvedLimit #### Fields --- * ``balance`` - [`[ResolvedBalanceLimit!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-balance-limit) * A resolved balance limit. ## ResolvedVelocityControl #### Fields --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier of this control. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Journal this velocity control is acting on. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this control --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this control. --- * ``enforcement`` - [`VelocityEnforcement!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-enforcement) * The enforcement this control produces. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if control should enforce control. The `account`, `transaction`, `balance` and `entry` are available for use in the dimension computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``limits`` - [`[ResolvedVelocityLimit!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-limit) * Set of resolved limits for this control. ## ResolvedVelocityControlConnection #### Fields --- * ``nodes`` - [`[ResolvedVelocityControl]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control) * --- * ``edges`` - [`[ResolvedVelocityControlConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ResolvedVelocityControlConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`ResolvedVelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-velocity-control) * ## ResolvedVelocityLimit #### Fields --- * ``calculationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Calculation identifier for checking balances on this resolved velocity limit --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this velocity limit. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this limit. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * " Human readable description of this limit. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if an balance entry should be written. The `account`, `transaction` and `entry` are available for use in the dimension computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``window`` - [`[PartitionKey!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * Group by these values to index the calculation. The `account`, `transaction`, `tranCode` and `entry` are available for use in the dimension computation on `context.vars`. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * The currency this limit applies to. If an empty string, applies to all limits. --- * ``params`` - [`[ParamDefinition]`](https://www.twisp.com/docs/reference/graphql/types/object.md#param-definition) * Parameters for `VelocityLimit.limit` --- * ``limit`` - [`ResolvedLimit!`](https://www.twisp.com/docs/reference/graphql/types/object.md#resolved-limit) * The resolved values for this velocity limit. ## RestoreOutput #### Fields --- * ``execution_id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. ## RestoreStatus #### Fields --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``status`` - [`RestoreStatusEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#restore-status-enum) * --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## ResultKeyConnection #### Fields --- * ``nodes`` - [`[String]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``edges`` - [`[ResultKeyConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#result-key-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ResultKeyConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## SQLColumnMetadata #### Fields --- * ``columnDefault`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``isCaseSensitive`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``isCurrency`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``isSigned`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``label`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``length`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``name`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``nullable`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``precision`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``scale`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``schemaName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``tableName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``typeName`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## SQLField #### Fields --- * ``type`` - [`SQLField_Type!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#sqlfield-type) * --- * ``value`` - [`SQLField_Value`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlfield-value) * ## SQLField_Value #### Fields --- * ``isNull`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``bytes`` - [`Uint8Array`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uint8array) * Uint8Array is a []uint8 of big-endian encoded binary data --- * ``bool`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. --- * ``double`` - [`Float`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#float) * The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point). --- * ``int`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- * ``str`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. ## SQLRecord #### Fields --- * ``fields`` - [`[SQLField]`](https://www.twisp.com/docs/reference/graphql/types/object.md#sqlfield) * ## Schedule #### Fields --- * ``jobType`` - [`JobType!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#job-type) * The job type to create the schedule for. Currently only one schedule per job-type is supported. --- * ``jobName`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A job name that's unique per job type. --- * ``principal`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The Twisp principal to run the job on a schedule. This should have a matching `client` policy. --- * ``scheduleExpression`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A schedule expression to run this job on. cron/rate/once supported see https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html for valid syntax. --- * ``timezone`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The timezone to run this schedule on based on https://www.iana.org/time-zones example: "America/Los_Angeles" or "UTC" Supports ST rules defined in https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html --- * ``metadata`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON metadata to pass to running job. ## Tenant A Tenant represents an environment within an organization, typically associated with a specific application, service, or set of resources. Tenants contain isolated ledgers, each deployed to a specific region. Tenants are useful for isolating data and configurations between different environments. Each tenant is uniquely identified by an accountId, which in combination with an AWS region, is used to calculate the database tenant for data isolation purposes. #### Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the tenant. --- * ``organizationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the tenant's parent organization. --- * ``accountId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A globally unique identifier representing an environment within the organization. This accountId, when combined with an AWS region, is used to calculate the database tenant. The name follows the S3 bucket naming rules: 3 to 63 characters of lowercase letters, numbers, periods, and hyphens, beginning and ending with a letter or a number, with no two adjacent periods, and not formatted as an IP address. An accountId cannot begin with `alias`, which is reserved for the qualified form of the `x-twisp-account-id` header. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A human-friendly name for the tenant, used for display purposes and easier identification. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * A brief description of the tenant, providing additional context about its purpose or characteristics. --- * ``created`` - [`Timestamp`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * The timestamp when the tenant was created. Null for tenants that predate this field. --- * ``ephemeral`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Whether the tenant is ephemeral and will be automatically deleted after 60 days. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this tenant. Updates will increment the version. ## TenantConnection Connection to a list of Tenant nodes. Access Tenant nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Tenant]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) * A Tenant represents an environment within an organization, typically associated with a specific application, service, or set of resources. Tenants contain isolated ledgers, each deployed to a specific region. Tenants are useful for isolating data and configurations between different environments. Each tenant is uniquely identified by an accountId, which in combination with an AWS region, is used to calculate the database tenant for data isolation purposes. --- * ``edges`` - [`[TenantConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant-connection-edge) * Edges represent links connecting a parent or query field to a list of Tenant nodes. They contain a reference to the Tenant node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## TenantConnectionEdge Edges represent links connecting a parent or query field to a list of Tenant nodes. They contain a reference to the Tenant node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Tenant`](https://www.twisp.com/docs/reference/graphql/types/object.md#tenant) * Reference to the Tenant node at this edge. ## TranCode Transaction Codes (tran codes) are how financial engineers do double-entry accounting. They encode the basic patterns for a type of transaction as a predictable and repeatable formula. You can think of tran codes as function signatures which define how a transaction acts upon the ledger. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `tc:` where `key` is `base64(json({ 1: tranCodeId }))`. --- * ``tranCodeId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Internal UUID for the transaction code record. --- * ``code`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The tran code represented as a unique string identifier. The code itself is a shorthand for the behavior represented. For example, the code `ACH_CREDIT` may represent a transaction writing two entries: an `ACH_DR` entry and an `ACH_CR` entry. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Explanation of what this tran code represents and how it should be used. This provides documentation for the tran code. --- * ``params`` - [`[ParamDefinition]`](https://www.twisp.com/docs/reference/graphql/types/object.md#param-definition) * Defines the parameters that can be used when posting transactions using this tran code. --- * ``transaction`` - [`TranCodeTransaction!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-transaction) * Definition of the transaction posted when this tran code is invoked. --- * ``entries`` - [`[TranCodeEntry!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-entry) * Definition of the entries written when transactions are posted with this tran code. --- * ``status`` - [`Status!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#status) * Operational status of the tran code. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Metadata attached to this tran code. --- * ``vars`` - [`ExpressionNestedMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-nested-map) * CEL expressions that are evaluated before transaction and entries and can be used a scratch pad area. --- * ``assertions`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Named boolean CEL expressions that must all evaluate to true when posting a transaction. Evaluated after params and vars are resolved. Failures return BadRequest. --- * ``workflow`` - [`TranCodeWorkflow`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-workflow) * Workflow execution definition triggered when this tran code is invoked. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the tran code was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this account. Previous versions are tracked in `history`. --- * ``history`` - [`TranCodeConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-connection) * History of changes to this TranCode record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. ## TranCodeConnection Connection to a list of TranCode nodes. Access TranCode nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[TranCode]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) * Transaction Codes (tran codes) are how financial engineers do double-entry accounting. They encode the basic patterns for a type of transaction as a predictable and repeatable formula. You can think of tran codes as function signatures which define how a transaction acts upon the ledger. --- * ``edges`` - [`[TranCodeConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code-connection-edge) * Edges represent links connecting a parent or query field to a list of TranCode nodes. They contain a reference to the TranCode node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## TranCodeConnectionEdge Edges represent links connecting a parent or query field to a list of TranCode nodes. They contain a reference to the TranCode node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`TranCode`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) * Reference to the TranCode node at this edge. ## TranCodeEntry Definition of an entry written when transactions are posted with this tran code. #### Fields --- * ``entryType`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Entry type for an entry written when this tran code is invoked. --- * ``accountId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Account ID for an entry written when this tran code is invoked. --- * ``layer`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Layer for an entry written when this tran code is invoked. --- * ``direction`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Direction for an entry written when this tran code is invoked. --- * ``units`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Units of currency for an entry written when this tran code is invoked. --- * ``currency`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Currency used for an entry written when this tran code is invoked. --- * ``description`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Description for an entry written when this tran code is invoked. --- * ``metadata`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Metadata for entries posted with this tran code. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression that indicates if this entry should be written. @example("params.amount > decimal(0.00)") ## TranCodeTransaction Definition of the transaction posted when this tran code is invoked. #### Fields --- * ``effective`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Effective date for transactions posted with this tran code. --- * ``journalId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Journal ID for transactions posted with this tran code. --- * ``correlationId`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Correlation ID for transactions posted with this tran code. --- * ``externalId`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * External ID for transactions posted with this tran code. --- * ``description`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Description for transactions posted with this tran code. --- * ``metadata`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Metadata for transactions posted with this tran code. ## TranCodeWorkflow Definition for workflow execution triggered by a tran code. #### Fields --- * ``workflowId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression that evaluates to the workflow ID (UUID). --- * ``executionId`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression that evaluates to the execution ID (UUID). --- * ``task`` - [`Expression!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * CEL expression that evaluates to the task name (String). --- * ``params`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of param names to CEL expressions for workflow params. ## Transaction Transactions record all accounting events in the ledger. In Twisp, the only way to write to a ledger is through a transaction. Every transaction writes two or more entries to the ledger in standard double-entry accounting practice. Twisp expands upon the basic principle of an accounting transaction with additional features like transaction codes and correlations. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `tx:` where `key` is `base64(json({ 1: transactionId }))`. --- * ``transactionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the transaction. --- * ``tranCodeId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the tran code used by this transaction. --- * ``journalId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for the journal this transaction applies to. --- * ``correlationId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows related transactions to be grouped. When a transaction is posted without a `correlationId`, it uses the `transactionId` as the `correlationId`. Then, future related transactions can be posted with the same `correlationId` to indicate their relationship to the original. This is very useful for events like holds, auths, auth reversals, etc. For example, consider the following (simplified) list of transactions: (ID: 1) Place card hold for $50 on account A (correlation ID: 1) (ID: 2) Place card hold for $20 on account B (correlation ID: 2) (ID: 3) Release card hold for $50 on account A (correlation ID: 1) Because transaction (3) is _related_ to transaction (1), it shares the same correlation ID. This way, we can easily observe the entire history of a multi-transaction event by querying the correlated transactions. --- * ``externalId`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Allows specifying a unique external ID associated with this transaction. --- * ``effective`` - [`Date!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#date) * The effective date records when the transaction is recorded as occurring for accounting purposes. Determines the accounting period within which the transaction is counted. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Description of the transaction. --- * ``metadata`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Arbitrary structured data about this transaction. --- * ``voidedBy`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The voided by records the transaction identifier that voided this transaction. --- * ``voidOf`` - [`UUID`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The void of records the transaction identifier this transaction is voiding --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the transaction was first posted. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``properties`` - [`TransactionProperties!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-properties) * --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this transaction. Previous versions are tracked in `history`. --- * ``correlated`` - [`TransactionConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-connection) * List of all correlated transactions. These are transactions which share the same `correlationId`. --- * ``entries`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * Ledger entries written by the transaction. --- * ``history`` - [`TransactionConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-connection) * History of changes to this Transaction record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. --- * ``journal`` - [`Journal!`](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) * Reference to the journal this transaction applies to. --- * ``tranCode`` - [`TranCode!`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) * Reference to the tran code used by this transaction. --- * ``exceptions`` - [`[TransactionException]`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-exception) * Reference to any exceptions, if occurred. --- * ``workflows`` - [`WorkflowExecutionConnection`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution-connection) * Look up the workflow executions that produced this transaction. ## TransactionConnection Connection to a list of Transaction nodes. Access Transaction nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[Transaction]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) * Transactions record all accounting events in the ledger. In Twisp, the only way to write to a ledger is through a transaction. Every transaction writes two or more entries to the ledger in standard double-entry accounting practice. Twisp expands upon the basic principle of an accounting transaction with additional features like transaction codes and correlations. --- * ``edges`` - [`[TransactionConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction-connection-edge) * Edges represent links connecting a parent or query field to a list of Transaction nodes. They contain a reference to the Transaction node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## TransactionConnectionEdge Edges represent links connecting a parent or query field to a list of Transaction nodes. They contain a reference to the Transaction node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`Transaction`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) * Reference to the Transaction node at this edge. ## TransactionException #### Fields --- * ``type`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``message`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``detail`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. ## TransactionProperties #### Fields --- * ``overrideVelocityEnforcement`` - [`VelocityEnforcement`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-enforcement) * Overrides velocity enforcements that have an action of `VOID` or `REJECT`. Useful for forced postings that require disabled velocity control enforcement (e.g. set to `WARN`). ## Upload #### Fields --- * ``key`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of file. e.g. `path/to/file.json` --- * ``uploadURL`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Presigned URL for uploading the actual file. --- * ``uploadURLExpiration`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Timestamp of when presigned url expires. If expired before file uploaded will need to create new upload. --- * ``uploadHeaders`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Headers to include in the upload request. --- * ``contentType`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * `contentType` of file. Currently only type supported is `application/json`. File should be array of json objects to pass to bulk query as variables, each item in array representing a single execution of the query. --- * ``contentEncoding`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * `Content-Encoding` of the file. When set, the upload should use this encoding (e.g. `gzip`). ## Usage #### Fields --- * ``readUnits`` - [`[UsageDatum]`](https://www.twisp.com/docs/reference/graphql/types/object.md#usage-datum) * The number of read units in the period listed. --- * ``writeUnits`` - [`[UsageDatum]`](https://www.twisp.com/docs/reference/graphql/types/object.md#usage-datum) * The number of write units in the period listed. --- * ``warehouseRPUSeconds`` - [`[UsageDatum]`](https://www.twisp.com/docs/reference/graphql/types/object.md#usage-datum) * The number of RPU seconds charged. Twisp bills per hour so divide `warehouseRPUSeconds.units / 3600` for billing purposes. ## UsageDatum #### Fields --- * ``period`` - [`Date`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#date) * Date in YYYY-MM-DD format. --- * ``units`` - [`Int`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## User A human user within the organization. Users can belong to multiple groups, which define their permissions within the organization based on the associated policies of each group. The user's effective permissions are determined by the combined set of policies from all their groups. A user is uniquely identified by their email address. #### Fields --- * ``id`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique ID for the user. --- * ``organizationId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * ID of the user's parent organization. --- * ``groupIds`` - [`[UUID!]!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * A list of unique identifiers for the groups to which the user belongs. The user's permissions are determined by the combined policies of these groups. --- * ``email`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The user's email address, which serves as a unique identifier and primary means of contact. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this user. Updates will increment the version. --- * ``mfaEnabled`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Returns if the users MFA is enabled. ## UserConnection Connection to a list of User nodes. Access User nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[User]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#user) * A human user within the organization. Users can belong to multiple groups, which define their permissions within the organization based on the associated policies of each group. The user's effective permissions are determined by the combined set of policies from all their groups. A user is uniquely identified by their email address. --- * ``edges`` - [`[UserConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#user-connection-edge) * Edges represent links connecting a parent or query field to a list of User nodes. They contain a reference to the User node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## UserConnectionEdge Edges represent links connecting a parent or query field to a list of User nodes. They contain a reference to the User node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`User`](https://www.twisp.com/docs/reference/graphql/types/object.md#user) * Reference to the User node at this edge. ## VelocityBalance #### Fields --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The matching velocity control id --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * The matching velocity limit. --- * ``spent`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * The amount spent on the limit. --- * ``remaining`` - [`Decimal!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#decimal) * The amount remaining on the limit. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * The currency of this velocity balance. --- * ``velocityLimit`` - [`VelocityLimit!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) * Get the velocity limit for this Balance. --- * ``balance`` - [`Balance!`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) * The underlying balance for this velocity. --- * ``entries`` - [`EntryConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry-connection) * Retrieve the entries in this window. ## VelocityControl #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. --- * ``velocityControlId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier of this control. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this control. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this control. --- * ``enforcement`` - [`VelocityEnforcement!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-enforcement) * The the enforcement this control produces. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if control should enforce. The `account`, `transaction`, `balance` and `entry` are available for use in the dimension computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``limits`` - [`[VelocityLimit]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) * Set of default velocity limits for this control. ## VelocityControlConnection #### Fields --- * ``nodes`` - [`[VelocityControl]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) * --- * ``edges`` - [`[VelocityControlConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## VelocityControlConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`VelocityControl`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-control) * ## VelocityEnforcement #### Fields --- * ``action`` - [`VelocityEnforcementAction!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#velocity-enforcement-action) * ## VelocityLimit #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. --- * ``velocityLimitId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Unique identifier for this velocity limit. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable name of this limit. --- * ``description`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * " Human readable description of this limit. --- * ``window`` - [`[PartitionKey]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * Group by these values to index the calculation. The `account`, `transaction`, `tranCode` and `entry` are available for use in the dimension computation on `context.vars`. --- * ``condition`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * A boolean expression indicating if an balance entry should be written. The `account`, `transaction` and `entry` are available for use in the dimension computation on `context.vars`. @example("has(context.vars.account.metadata.policyPayment)") --- * ``limit`` - [`Limit!`](https://www.twisp.com/docs/reference/graphql/types/object.md#limit) * The limit to enforce. --- * ``currency`` - [`CurrencyCode!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#currency-code) * The currency this limit applies to. If an empty string, applies to all limits. --- * ``params`` - [`[ParamDefinition]`](https://www.twisp.com/docs/reference/graphql/types/object.md#param-definition) * Parameters for `VelocityLimit.limit` ## VelocityLimitConnection #### Fields --- * ``nodes`` - [`[VelocityLimit]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) * --- * ``edges`` - [`[VelocityLimitConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## VelocityLimitConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`VelocityLimit`](https://www.twisp.com/docs/reference/graphql/types/object.md#velocity-limit) * ## View Represents an view materialized view. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for a record to support Global Object Identification. Uses format `ag:`. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this view. Typically human readable. --- * ``document`` - [`[DocumentElement!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#document-element) * The document produced by this view. --- * ``sources`` - [`[ViewSource!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-source) * List of source tables that trigger updates to this view. --- * ``partition`` - [`[PartitionKey!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * Dimensions define the partition for the view. --- * ``sort`` - [`[IndexKey!]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-key) * The sort key to use for supporting range queries. --- * ``filters`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Filters that determine when the view should be updated. Only source changes that satisfy these conditions will trigger an update. --- * ``description`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Human readable description of this view. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Creation timestamp of this view. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Lat modified timestamp of this view. --- * ``config`` - [`ViewConfig!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-config) * Configuration including concurrent enablement. --- * ``viewId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Twisp generated internal view identifier. --- * ``normalize`` - [`Expression`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression) * Expression that this view is normalized by. --- * ``indexes`` - [`[ViewIndex]`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-index) * --- * ``searchIndexes`` - [`[ViewSearchIndex]`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-search-index) * --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this view. ## ViewConfig #### Fields --- * ``enableConcurrentPosting`` - [`Boolean!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * The `Boolean` scalar type represents `true` or `false`. ## ViewConnection Connection to a list of View nodes. Access View nodes directly through the `nodes` field, or access information about the connection edges with the `edges` field. Use `pageInfo` to paginate responses using the cursors provided. #### Fields --- * ``nodes`` - [`[View]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view) * Represents an view materialized view. --- * ``edges`` - [`[ViewConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-connection-edge) * Edges represent links connecting a parent or query field to a list of View nodes. They contain a reference to the View node and metadata like the `cursor` position for the edge. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ViewConnectionEdge Edges represent links connecting a parent or query field to a list of View nodes. They contain a reference to the View node and metadata like the `cursor` position for the edge. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`View`](https://www.twisp.com/docs/reference/graphql/types/object.md#view) * Reference to the View node at this edge. ## ViewIndex #### Fields --- * ``indexId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Twisp generated internal index identifier. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``unique`` - [`Boolean`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#boolean) * Indicates if this index is unique. --- * ``partition`` - [`[PartitionKey]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#partition-key) * The partition key used for this index. --- * ``partitionShardCount`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * Specifies the number of shards for partition write scaling. This parameter defines how many shards the partition key is automatically split into, similarly to RAID-style disk striping. Increasing this value allows the index to distribute write throughput across multiple shards while sacrificing global sort order on the partition. For instance, setting `partitionShardCount` to 4 splits each unique partition into four shards, effectively allowing 4000 writes per second for a single partition key. --- * ``sort`` - [`[IndexKey]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#index-key) * The sort key to use for supporting range queries. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. ## ViewRecord Represents a single entry in an view materialized view. #### Fields --- * ``id`` - [`ID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#id) * Globally unique identifier for this view entry. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Name of the view this record is from. --- * ``document`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The document content of this view entry. Structure depends on the view definition. --- * ``source`` - [`ViewTrigger!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-trigger) * Information about the data source that trigged this version of the document. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The current version number of this view. --- * ``history`` - [`ViewRecordConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-record-connection) * History of changes to this View record. Because ledgers are immutable and append-only, all changes are recorded as sequenced versions of the record, providing an unbroken lineage of the current state. ## ViewRecordConnection Connection to a list of ViewEntry nodes. #### Fields --- * ``nodes`` - [`[ViewRecord]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-record) * Represents a single entry in an view materialized view. --- * ``edges`` - [`[ViewRecordConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-record-connection-edge) * Edges represent links connecting a parent or query field to a list of ViewEntry nodes. --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## ViewRecordConnectionEdge Edges represent links connecting a parent or query field to a list of ViewEntry nodes. #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Cursor position at this edge. --- * ``node`` - [`ViewRecord`](https://www.twisp.com/docs/reference/graphql/types/object.md#view-record) * Reference to the ViewEntry node at this edge. ## ViewSearchIndex #### Fields --- * ``indexId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Twisp generated internal index identifier. --- * ``name`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Unique identifier of this index. Typically human readable. --- * ``constraints`` - [`ExpressionMap`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#expression-map) * Map of named CEL expressions specifying the conditions for including a record in this index. Records are only included in the index if _all_ expressions evaluate to `true`, i.e. they are combined with a logical AND. Each expression must return a boolean value. For example, a custom index on a `metadata.category` field might use the constraints `{ hasCategory: "has(document.metadata.category)" }` to ensure that only records whose `metadata` document has a defined value for the `category` field are included. --- * ``opensearchSchema`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * The Opensearch CEL expression schema to apply to the document prior to indexing. Only available on search indexes. ## ViewSource #### Fields --- * ``entity`` - [`ViewEntity!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#view-entity) * Enum of source tables that can trigger view updates. --- * ``triggers`` - [`[ViewTriggerEnum!]!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#view-trigger-enum) * ## ViewTrigger #### Fields --- * ``entity`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``trigger`` - [`ViewTriggerEnum!`](https://www.twisp.com/docs/reference/graphql/types/enum.md#view-trigger-enum) * --- * ``new`` - [`DatabaseEntity!`](https://www.twisp.com/docs/reference/graphql/types/union.md#database-entity) * Resolve the new trigger entity that created this version of the document. --- * ``old`` - [`DatabaseEntity`](https://www.twisp.com/docs/reference/graphql/types/union.md#database-entity) * Resolve the old trigger entity that created this version of the document. ## WorkflowActivity #### Fields --- * ``action`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entity`` - [`WorkflowEntity!`](https://www.twisp.com/docs/reference/graphql/types/union.md#workflow-entity) * --- * ``entityId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``entityType`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## WorkflowExecution #### Fields --- * ``workflowId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Workflow Id of workflow invoked. --- * ``executionId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * Execution Id of this execution. --- * ``task`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * The task that was invoked on this version of the workflow execution. --- * ``params`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Parameters supplied for this workflow execution. --- * ``context`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Context to pass along to future executions of this workflow. --- * ``output`` - [`WorkflowExecutionOutput!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution-output) * Output of this invocation of the workflow. --- * ``error`` - [`String`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#string) * Errors from this invocation of the workflow. --- * ``created`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Date and time when the execution was first created. --- * ``modified`` - [`Timestamp!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#timestamp) * Time of the last change. Especially useful when reviewing the `history`. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * version number of the execution. Previous versions are tracked in history. --- * ``activities`` - [`[WorkflowActivity]`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-activity) * Activities that this workflow took. It may have inserted entities like Transactions or invoked Workflows. --- * ``history`` - [`WorkflowExecutionConnection!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution-connection) * Workflow execution history for this workflow. --- * ``state`` - [`JSON!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * Outputs the execution state of the workflow. Depending on the workflow will contain diagnostic detials specific to the workflow. --- * ``transactions`` - [`[Transaction]`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) * Resolve any posted transactions that this workflow posted in this invocation. ## WorkflowExecutionConnection #### Fields --- * ``nodes`` - [`[WorkflowExecution]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) * --- * ``edges`` - [`[WorkflowExecutionConnectionEdge]!`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution-connection-edge) * --- * ``pageInfo`` - [`PageInfo!`](https://www.twisp.com/docs/reference/graphql/types/object.md#page-info) * ## WorkflowExecutionConnectionEdge #### Fields --- * ``cursor`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``node`` - [`WorkflowExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) * ## WorkflowExecutionOutput #### Fields --- * ``state`` - [`JSON`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#json) * JSON object. --- * ``entities`` - [`[WorkflowExecutionOutputEntity]`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution-output-entity) * ## WorkflowExecutionOutputEntity #### Fields --- * ``action`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``entity`` - [`WorkflowEntity!`](https://www.twisp.com/docs/reference/graphql/types/union.md#workflow-entity) * --- * ``entityId`` - [`UUID!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#uuid) * 128-bit universally unique identifier (UUID). Used for most ID fields on records. --- * ``entityType`` - [`String!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#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. --- * ``version`` - [`Int!`](https://www.twisp.com/docs/reference/graphql/types/scalar.md#int) * The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. --- # Scalar Types Scalar types represent primitive values like strings, integers, and booleans. ## Boolean The `Boolean` scalar type represents `true` or `false`. ## CurrencyCode ISO 4217 standard three-character code indicating the currency. _Examples:_ - ``'USD'`` - ``'CHF'`` ## Date Date in YYYY-MM-DD format. _Example:_ ``'2022-08-18'`` ## Decimal Decimal is a fixed-precision data type supporting exact representation of numeric values. _Example:_ ``105.92851`` ## EntryType String value for an entry type. _Example:_ ``'ACH_CR'`` ## Expression A literal CEL expression to be evaluated. ## 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()" } ## ExpressionNestedMap A nested 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()", "obj": { "foo": "'bar'" } } ## ExpressionValue A Value-shaped CEL template. String leaves are CEL expressions; objects and lists recurse; non-string leaves are literal values. ## Float The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point). ## ID The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. ## Int The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ## InterpolatedExpression Interpolated string expression. Values within `{{}}` are evaluated as a CEL expression. Examples: - `Current time: {{time.Now()}}` => `"Current time: 2022-04-27T10:50:00.000Z"` - `Raw String` => `"Raw String"` - `{{uuid.New()}}` => `"9dd984db-78d8-420f-9380-80e3cf36fe75"` ## JSON JSON object. _Example:_ ```{ "counts": 12, "name": "Metric A" }``` ## 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. ## Timestamp [RFC3339-compliant](https://www.rfc-editor.org/rfc/rfc3339) UTC timestamp. _Example:_ ``'2022-04-27T10:50:00.000Z'`` ## UUID 128-bit universally unique identifier (UUID). Used for most ID fields on records. _Example:_ ``'3ea12e45-7df2-4293-9434-feb792affc91'`` ## Uint8Array Uint8Array is a []uint8 of big-endian encoded binary data ## Value Value object. Similar to the JSON object with support for type coersion _Example:_ ```{ "int": 12, "float": 1.732, "uuid": "D3DC5ED3-23D0-4924-BAE1-9AA026BACE09"}``` --- # Union Types Union types combine two or more object types into a single type to represent data that can be one of multiple types. ## AccountSetMember Account set members can be of type Account or AccountSet. #### Possible Types - [`Account`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) - [`AccountSet`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) ## AchRecord #### Possible Types - [`AchFile`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-file) - [`AchBatch`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-batch) - [`AchIatBatch`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-iat-batch) - [`AchEntryDetail`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-entry-detail) - [`AchAdvEntryDetail`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-adv-entry-detail) - [`AchIatEntryDetail`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-iat-entry-detail) ## DatabaseEntity #### Possible Types - [`Account`](https://www.twisp.com/docs/reference/graphql/types/object.md#account) - [`AccountSet`](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) - [`Balance`](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) - [`Entry`](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) - [`Transaction`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) - [`TranCode`](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) ## WorkflowEntity #### Possible Types - [`Transaction`](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) - [`WorkflowExecution`](https://www.twisp.com/docs/reference/graphql/types/object.md#workflow-execution) - [`AchWorkflowTrace`](https://www.twisp.com/docs/reference/graphql/types/object.md#ach-workflow-trace) --- # Reference Definitions of all components in the Twisp Accounting Core and GraphQL API. ## Reference Sections - [Ledger](https://www.twisp.com/docs/reference/ledger.md): Ledger resources in the Twisp accounting core. - [ACH](https://www.twisp.com/docs/reference/ach.md): ACH resources in the Twisp accounting core. - [GraphQL](https://www.twisp.com/docs/reference/graphql.md): Type definitions for the full GraphQL schema. - [API](https://www.twisp.com/docs/reference/api.md): Key components and concepts for interacting with the API. - [CEL](https://www.twisp.com/docs/reference/cel.md): Packages and functions available in the common expression language runtime. ## Type Diagrams Use these diagrams for a high-level overview of the type system within the Twisp ledger. ### Basic Relationships Simplified type relationship diagram showing basic connections between types. - [Journals](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) have many [Transactions](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) and [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) - [Transactions](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) are defined by their [TranCode](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code) and write multiple [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) to the ledger. - [Transactions](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) can be linked to other correlated [Transactions](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) - [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) are written to a specific [Account](https://www.twisp.com/docs/reference/graphql/types/object.md#account) and [Journal](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) - [Accounts](https://www.twisp.com/docs/reference/graphql/types/object.md#account) roll up a [Balance](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) of all [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) for each [Journal](https://www.twisp.com/docs/reference/graphql/types/object.md#journal) - [Account Sets](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) are groupings of [Accounts](https://www.twisp.com/docs/reference/graphql/types/object.md#account) and/or other [Account Sets](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) which also roll up [Balances](https://www.twisp.com/docs/reference/graphql/types/object.md#balance) ![Simplified entity relationship diagram for Twisp core](https://www.twisp.com/docs/images/diagrams/core_erd_minimal.svg) ### Entity Relationship Diagram Although the Twisp core is not a relational database, it does enforce referential integrity between related records and thus we can model it with an RDB-style ERD. Only select fields for each type have been shown in this diagram to aid readability. For the full reference of each type, see the [GraphQL reference](https://www.twisp.com/docs/reference/graphql.md). ![RDB-style entity relationship diagram for Twisp core](https://www.twisp.com/docs/images/diagrams/core_erd.svg) --- # Account Sets Reference for the account set resource within a Twisp Ledger. ## The Basics Account sets allow you to group and organize accounts within the Twisp Accounting Core, providing a structured way to manage and visualize your chart of accounts. > **Note:** > > Account Sets are how you create **custom groupings of accounts** for better organization and **multi-account balance materializations**. Instead of using a single hierarchical tree to model your chart of accounts, account sets offer a more dynamic approach. They are custom groups of accounts that aggregate balances and provide a unified interface into the entries for all accounts within the set. ## Components of Account Sets There are 5 key components that make up account sets: 1. **Members**: either accounts or other account sets. This flexibility allows you to create more complex structures for your chart of accounts, as you can nest sets within other sets. 2. **Sets**: reference the other sets (if any) which contain this set as a member. 3. **Balances**: represent the sum of all balances of member accounts and member account sets. Balances are computed for every currency and layer used by the entries posted to accounts in a set and all of its sub-sets. 4. **Journal**: associates the account set with a specific journal. Account sets only compute balances using entries posted to their associated journal. 5. **Normal Balance Type**: determines how the account set's normal balances are computed, just like for accounts. In addition, account sets have other properties which are common to most or all resources in the accounting core: - **ID**: a universally unique identifier (UUID) for the account set. - **Name**: a descriptive name to identify the account set. - **Description**: a free-form text to be used for describing anything about the account set. We recommend using this field to summarize what the account set is for and when it should be used. - **Metadata**: unstructured, user-specified JSON. Can be combined with custom indexes for powerful querying capacities. - **Config**: allows setting up an account set for concurrent posting. - **Created & Updated Timestamps**: self-evident: when the account set was created and when it was last updated. - **Version & History**: account sets, like every other record in the accounting core, maintain a list of all changes made to them in their `history` field, and the `version` field indicates the current active version of the account set. ## Nesting and Hierarchies in Account Sets Account sets in Twisp offer a flexible way to organize accounts into hierarchical structures. By nesting account sets within other account sets, complex structures can be modeled to better fit the needs of your business or organization. Nesting account sets is as simple as using the `addToAccountSet` mutation and specifying the `memberType` as `ACCOUNT_SET`. Here's an example: ```graphql mutation AddToAccountSetNested( addToAccountSet( id: "" member: { memberId: "", memberType: ACCOUNT_SET } ) { accountSetId members(first: 10) { nodes { __typename ... on AccountSet { accountSetId name } } } } ) ``` By following this approach, you can create tree-like structures and organize accounts in a way that suits your specific use case. Here's an example of a tree structure that can be created using nested account sets: ```mermaid graph BT 1 & 2 & Y --> X 3 --> Y ``` In this example, we have an account set "X" which contains account #1, account #2, and a nested account set "Y" which contains account #3. ## Account Set Operations Use GraphQL queries and mutations to read, create, add members to, update, and delete (lock) account sets: - [`Query.accountSet()`](https://www.twisp.com/docs/reference/graphql/queries.md#account-set): Get a single account set. - [`Query.accountSets()`](https://www.twisp.com/docs/reference/graphql/queries.md#account-sets): Query account sets using index filters. - [`Mutation.createAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-account-set): Create a new account set. - [`Mutation.addToAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#add-to-account-set): Add a member (account or account set) to an existing account set. - [`Mutation.removeFromAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#remove-from-account-set): Remove a member from an existing account set. Account members are removed normally. A sub-set (account set member) can only be removed while it has never been populated — with one exception: a sub-set that has been soft-deleted may be removed from its parents once it is empty and past its drain window (see the guide on [restructuring a chart of accounts](https://www.twisp.com/docs/tutorials/restructuring-a-chart-of-accounts.md)). - [`Mutation.updateAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-account-set): Update select fields for an existing account set. - [`Mutation.deleteAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-account-set): Soft delete (lock) a specified account set. This is mark-only: it always succeeds, marks the set as deleted, and does not remove members or detach the set from its parents. A deleted set can no longer be added to another set or accept new members, and the mark is permanent (there is no un-delete). ## Further Reading To learn how to work with account sets, see the tutorial on [Organizing With Account Sets](https://www.twisp.com/docs/tutorials/organizing-with-account-sets.md). To safely tear down or reorganize an existing hierarchy, see the guide on [Restructuring A Chart Of Accounts](https://www.twisp.com/docs/tutorials/restructuring-a-chart-of-accounts.md). For more context on how and why Twisp uses account sets, see [Chart Of Accounts](https://www.twisp.com/docs/accounting-core/chart-of-accounts.md). To review the GraphQL docs for the `AccountSet` type, see [AccountSet](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set). --- # Accounts Reference for the account resource within a Twisp Ledger. ## The Basics Accounts are a named **store of value** that hold a balance, as well as a **record of activity** in the form of ledger entries posted to them. They are an essential part of the Twisp accounting core and are used to model all of the economic activities your ledger provides. Additionally, organizing accounts into sets allows for easy aggregation of balances and querying of ledger entries, enabling you to create a more flexible and powerful structure for your chart of accounts. ## Components of Accounts There are 5 key components defining an account: 1. **Code**: a unique name to identify the account, usually formatted in UPPER_SNAKE_CASE. 2. **Balances**: reflect the net result of all transactions affecting the account. Balances are materialized for each layer, currency, and journal used by entries in the account. 3. **Entries**: the individual journal entries written in transactions posted to the account, providing a detailed history of all financial events that have affected the account over time. 4. **Sets**: list the account sets of which this account is a member. 5. **Normal Balance Type**: determines how the account's normal balances are computed. In addition, accounts have other properties which are common to most or all resources in the accounting core: - **ID**: a universally unique identifier (UUID) for the account. - **Name**: a descriptive name. - **Description**: a free-form text to be used for describing anything about the account. We recommend using this field to summarize what the account is for and when it should be used. - **Metadata**: unstructured, user-specified JSON. Can be combined with custom indexes for powerful querying capacities. - **Config**: allows setting up an account for concurrent posting. - **Created & Updated Timestamps**: self-evident: when the account was created and when it was last updated. - **Version & History**: accounts, like every other record in the accounting core, maintain a list of all changes made to them in their `history` field, and the `version` field indicates the current active version of the account. ## Account Operations Use GraphQL queries and mutations to read, create, update, and delete (lock) accounts: - [`Query.account()`](https://www.twisp.com/docs/reference/graphql/queries.md#account): Get a single account. - [`Query.accounts()`](https://www.twisp.com/docs/reference/graphql/queries.md#account-sets): Query accounts using index filters. - [`Mutation.createAccount()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-account): Create a new account. - [`Mutation.updateAccount()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-account): Update select fields for an existing account. - [`Mutation.deleteAccount()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-account): Soft delete (lock) a specified account. - [`Mutation.addToAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#add-to-account-set): Add an account to a set. - [`Mutation.removeFromAccountSet()`](https://www.twisp.com/docs/reference/graphql/mutations.md#remove-from-account-set): Remove an account from a set. ## Further Reading To learn how to work with accounts, see the tutorial on [Setting Up Accounts](https://www.twisp.com/docs/tutorials/setting-up-accounts.md). For more context on how and why Twisp uses accounts, see [Chart Of Accounts](https://www.twisp.com/docs/accounting-core/chart-of-accounts.md). To review the GraphQL docs for the `Account` type, see [Account](https://www.twisp.com/docs/reference/graphql/types/object.md#account). --- # Balances Reference for the balance resource within a Twisp Ledger. ## The Basics Balances are auto-calculated sums of the entries for a given account or account set, providing a snapshot a financial position. Balances play a crucial role in accounting, as they provide a snapshot of an account's value at any given time. In the Twisp system, accounts and balances are closely related. Balances in Twisp... - Are automatically calculated as entries are written - Separate debit and credit balances maintained - Are attached to a specific account, journal, and currency - Roll up into normal balances based on account's normal balance type ## Components of a Balance Record - **Account**: determines which account's entries the balance is computed with. - **Entries**: list all the entries used to compute the balance. The most recent entry is also stored as a reference. - **Journal**: is the journal from which entries are pulled to compute the balance. Each account's balance is calculated per journal. - **Currency**: is the currency used by entries in the balance. - **Balance Amounts** for each layer (SETTLED, PENDING, ENCUMBRANCE, and the dynamic AVAILABLE layer), which contain the sums for... - The **debit** balance of the account - The **credit** balance of the account - The **normal** balance, which is calculated difference between credits and debits (for credit-normal accounts) or between debits and credits (for debit-normal accounts). Balance records also maintain `created`, `modified`, and `committed` timestamps as well as their [Versions And History](https://www.twisp.com/docs/reference/ledger/versions-and-history.md). ## Point-in-time Balances With [point-in-time queries](https://www.twisp.com/docs/reference/ledger/versions-and-history.md#point-in-time-queries), balance `history` is filterable by timestamp. This provides the ability to retrieve the active balance at a specific time. ## Balance Operations Use GraphQL queries to read balances directly: - [`Query.balance()`](https://www.twisp.com/docs/reference/graphql/queries.md#balance): Get a single balance. - [`Query.balances()`](https://www.twisp.com/docs/reference/graphql/queries.md#balances): Query balances using index filters. Balances can also be queried relationally as fields on the [Account](https://www.twisp.com/docs/reference/graphql/types/object.md#account) and [AccountSet](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set) objects. ## Further Reading To learn more about querying balances, see the tutorial on [Pulling Balances](https://www.twisp.com/docs/tutorials/pulling-balances.md). For more context on how balances work, see [Balances](https://www.twisp.com/docs/accounting-core/balances.md). To review the GraphQL docs for the `Balance` type, see [Balance](https://www.twisp.com/docs/reference/graphql/types/object.md#balance). --- # Entries Reference for the entry resource within a Twisp Ledger. ## The Basics Entries are records of a money movement into or out of an account in the Twisp ledger. They represent the individual line items in a ledger journal, storing details such as the account and posting transaction. > **Note:** > > In Twisp, an _entry_ is a fundamental accounting concept representing **one side of a transaction** in a ledger. Transactions are the only way to write to a Twisp ledger. Every transaction posted to a ledger writes at least two entries (one or more debits and one or more credits) which balance to zero, in accordance with double-entry accounting principles. This ensures that the accounting system maintains a high level of integrity and consistency in the ledger record. In other accounting systems, entries might be called "ledger lines" or "journal entries." However, the fundamental concept remains the same. In Twisp, entries always have an account, amount (in units of a currency), direction (`CREDIT` or `DEBIT`), and an entry type that assigns every entry to a categorical type. These entries are the building blocks of a comprehensive, accurate, and reliable financial record. ## Components of a Ledger Entry 1. **Account**: to which the entry is written. This account represents the financial aspect (e.g., asset, liability, expense) impacted by the entry. 2. **Amount**: expressed in numerical (decimal) **units** of a specified **currency** denomination. 3. **Direction**: denotes which side of the ledger the entry is posted on. This is a crucial aspect of double-entry accounting, as every transaction must have at least one entry on the debit side and one on the credit side. 4. **Layer**: on which this entry is recorded (SETTLED, PENDING, or ENCUMBRANCE). 5. **Type**: a categorical label for the entry, such as "TRANSFER_DR" for an entry representing the debit side of a transfer. 6. **Transaction**: references the transaction record in which the entry was written. 7. **Journal**: within which the entry was written. 8. **Sequence**: indicates the order in which the entry was written within the context of the posting transaction. In addition, entries have other properties which are common to most or all resources in the accounting core: - **ID**: a universally unique identifier (UUID) for the entry. - **Name**: a descriptive name. - **Description**: a free-form text to be used for describing anything about the entry. We recommend using this field to summarize what the entry is for and when it should be used. - **Metadata**: unstructured, user-specified JSON. Can be combined with custom indexes for powerful querying capacities. - **Created & Updated Timestamps**: self-evident: when the entry was created and when it was last updated. - **Version & History**: entries, like every other record in the accounting core, maintain a list of all changes made to them in their `history` field, and the `version` field indicates the current active version of the entry. ## Entry Operations Entries cannot be written directly, only indirectly by posting transactions. Entries can be queried using GraphQL: - [`Query.entry()`](https://www.twisp.com/docs/reference/graphql/queries.md#entry): Get a single entry. - [`Query.entries()`](https://www.twisp.com/docs/reference/graphql/queries.md#entries): Query entries using index filters. Entries can also be queried relationally as fields on the [Account](https://www.twisp.com/docs/reference/graphql/types/object.md#account), [AccountSet](https://www.twisp.com/docs/reference/graphql/types/object.md#account-set), [Balance](https://www.twisp.com/docs/reference/graphql/types/object.md#balance), and [Transaction](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) objects. ## Further Reading To learn how write entries through posting transactions, see the tutorial on [Posting Transactions](https://www.twisp.com/docs/tutorials/posting-transactions.md). For more context on how and why Twisp a layered accounting model, see [Layered Accounting](https://www.twisp.com/docs/accounting-core/layered-accounting.md). To review the GraphQL docs for the `Entry` type, see [Entry](https://www.twisp.com/docs/reference/graphql/types/object.md#entry). --- # Ledger Reference A Twisp ledger is composed of accounts, account sets, balances, entries, journals, transactions, and tran codes. ## Ledger Resources See each of the sub-pages in this reference for details about the corresponding ledger resource. Each resource is accessible via the [GraphQL API](https://www.twisp.com/docs/reference/graphql.md). - [Accounts](https://www.twisp.com/docs/reference/ledger/accounts.md): Accounts store value and record activity. - [Account Sets](https://www.twisp.com/docs/reference/ledger/account-sets.md): Account sets group and organize accounts, rolling up balances for member accounts. - [Balances](https://www.twisp.com/docs/reference/ledger/balances.md): Balances calculate sums of ledger entries across layers, journals, accounts, and currencies. - [Entries](https://www.twisp.com/docs/reference/ledger/entries.md): Entries are records of money movement into or out of accounts. - [Indexes](https://www.twisp.com/docs/reference/ledger/indexes.md): Indexes enable efficient data access in the ledger. - [KV Store](https://www.twisp.com/docs/reference/ledger/kv.md): KV records store transactional JSON documents by namespace and key. - [Journals](https://www.twisp.com/docs/reference/ledger/journals.md): Journals keep your financial transactions organized in separate collections. - [Tran Codes](https://www.twisp.com/docs/reference/ledger/tran-codes.md): Transaction codes define how ledger entries are written when a transaction is posted - [Transactions](https://www.twisp.com/docs/reference/ledger/transactions.md): Transactions record all accounting events in the ledger. - [Velocity Controls](https://www.twisp.com/docs/reference/ledger/velocity-controls.md): Velocity controls regulate the rate that transactions can be posted. ## Axioms Governing the Twisp Ledger _This set of axioms summarizes the key behavior of a Twisp ledger._ - **Accounts** are a named store of value in Twisp, with each account having a balance. - Accounts record activity in the form of ledger entries posted to them. - Accounts support multiple layers and have full support for multiple journals. - Accounts are stored as immutable documents with all changes stored in a versioned history. - **Account sets** are custom groups of accounts that aggregate balances and provide a unified interface into the entries for all accounts. - Account sets can contain other sets, allowing for the modeling of more complex structures for a chart of accounts. - A chart of accounts is a collection of account and account sets used to track money within the system. - Account sets belong to a single journal. - Account sets will materialize balances for entries posted to the account set's journal in accounts that are members of the account set or any of its descendant sets. - Entries can only be posted to accounts, not to account sets. - **Balances** are derived from entries written to the ledger. - Balances are calculated for every account. - Querying balances reflects the current state of accounts in the ledger. - Accounts have a debit balance, credit balance, and normal balance on each layer (SETTLED, PENDING, and ENCUMBRANCE). - Balances are materialized for every combination of account, journal, layer, and currency. - Balance calculations are computed on write, not on read. - **Entries** represent one side of a transaction in the Twisp ledger. - Entries always have an account, an amount (including currency), and a direction (CREDIT or DEBIT). - Entries can only be entered in the context of a transaction. - Every entry is assigned to a layer (SETTLED, PENDING, and ENCUMBRANCE) to differentiate between entries in various stages of a transaction lifecycle. - Posting a transaction will create at least 2 ledger entries. - **Journals** are used to organize transactions within separate "books" in the Twisp ledger. - Every ledger contains a default journal. - Users can create, update, and delete additional journals as needed. - **KV records** store arbitrary JSON documents by `(namespace, key)`. - KV records are versioned and maintain a history of changes. - KV records can be queried by namespace or by custom indexes created on `KV`. - **Transactions** record all accounting events in the Twisp ledger. - The only way to write to a ledger is through a transaction. - Every transaction writes two or more entries to the ledger in standard double-entry accounting practice. - Transactions are structured by the tran code used, ensuring that the ledger is consistent, predictable, and correct. - **Transaction codes** (tran codes) define how ledger entries are written in Twisp. - Tran codes accept input values as parameters and write a multi-entry transaction to the ledger. - Params are key-value parameters specified by the transaction code and are used when posting a transaction with a specified tran code. - All transactions using tran codes are executed atomically, ensuring all-or-nothing commits. - Tran codes provide a centralized interface for defining every type of transactional activity in a system. - **Velocity Controls** Define conditions under which a transaction is allowed to be written in Twisp. - Velocity Controls can apply to Accounts or Account Sets. --- # Indexes Reference for indexes within a Twisp Ledger. ## The Basics All data retrieval operations in Twisp are executed via indexes. This eliminates issues associated with table scans and dynamic query planning, providing consistent and predictable data access patterns. Indexes in Twisp are designed to support sophisticated application requirements: - **Transactionally Consistent Operations**: All database interactions via indexes are transactionally consistent, ensuring strong consistency. - **Enhanced Partition and Sorting Controls**: Twisp’s schema supports compound keys and multi-field sorting, allowing for precise control over how data is partitioned and ordered. - **Compatibility with All Fields**: Any field within the schema, including those within JSON metadata and List collection types, can be used to create an index. This flexibility allows users to tailor their indexing strategy to the specific needs of their application. - **Filterable with CEL Expressions**: Partial indexes can be created based on conditions specified in CEL (Common Expression Language) expressions, enabling targeted indexing of records that meet certain criteria. ## Types of Indexes Multiple index types are supported in Twisp. Each index type supports a unique set of data access patterns. By selecting the appropriate index type, users can optimize query performance and tailor data access to their specific application requirements within the Twisp system. A number of default indexes are included in the Twisp system. These built-in indexes are managed by Twisp to provide efficient query performance for common financial ledger operations. These indexes guarantee data integrity and are transactionally consistent, making them a reliable choice for most standard query operations. ### Custom Indexes Custom indexes in Twisp are pivotal for optimizing queries and structuring data access patterns specific to your application's needs. Custom indexes can be created for the following record types: - `AccountSet` - `Account` - `Balance` - `Entry` - `KV` - `TranCode` - `Transaction` This capability enables precise control over how data related to these records is indexed and accessed. Custom indexes are transactionally consistent. ### Historical Indexes Historical indexes are specialized indexes that allow querying across all versions of records' histories. Given Twisp’s immutable, append-only data store, any data change results in a new version of a record. Historical indexes enable sophisticated queries that include past record states, which regular indexes do not cover. - **Version Tracking:** Indexes every version of a record, enabling retrieval of historical data states. - **Advanced Query Capabilities:** Supports queries like retrieving account balances at specific points in time or finding record states when particular metadata values were set. ### Search Indexes Search indexes integrates OpenSearch's powerful search capabilities within the Twisp system, providing enhanced performance for text-based queries and structured data retrieval. Leveraging OpenSearch allows for full-text search, advanced filtering, and robust search ranking capabilities, enabling users to harness large datasets efficiently. - **Full-Text Search Capabilities**: OpenSearch indexes support search queries across textual data fields, allowing users to perform complex searches that include fuzzy matching, stemming, and tokenization. - **Rich Filtering Options**: Users can apply filters on various fields, such as numeric ranges, date intervals, or specific terms, making it easier to narrow down search results based on contextual requirements. ## Components of Indexes ### Index Key Fields Indexes in Twisp can be created using both root-level fields and nested fields within documents. This flexibility allows for comprehensive indexing strategies that can cater to complex data structures. For example, you can create custom index keys using: - Root-level fields such as `Account.modified`. - Nested fields within objects, such as fields within the arbitrary JSON `metadata` object in a record. This approach ensures the ability to index any data within the system. ### Index Expressions An index key need not be just a field of the underlying record, but can be a function or expression computed from one or more fields in the record. This feature is useful to obtain fast access to records based on the results of computations. ### Partition Keys When designing custom indexes, it's crucial to consider partitioning strategies to ensure performance and scalability. Partitioning by account is commonly sufficient, but specific workloads may necessitate alternative approaches. Be mindful of read and write operations per partition to prevent throttling, as the database supports a fixed amount of bandwidth and operations per second for each partition. ### Sort Keys For a specific partition key, sort keys allow all data that share that partition key to be sorted and retrieved efficiently based on application requirements. ### Unique Constraints Unique constraints ensure that the data contained in a field, or a group of fields, is unique across all records indexed. ### Partial Indexes Partial indexes can be created based on conditions specified in CEL (Common Expression Language) expressions, enabling targeted indexing of records that meet certain criteria. ### Asynchronous Indexes For indexes that may have a hot partition keys prone to throttling, often seen during high-volume data loads, asynchronous indexes can be used to populate the index via a background process. Asynchronous indexes are eventually consistent and unique constraints are not permitted. #### Built-In Async Indexes Several of the standard built-in indexes use asynchronous (eventually consistent) indexes. Results from these indexes may lag slightly behind recent writes. Some async indexes transparently delegate to a strongly consistent index when an `eq` filter is supplied. | Record Type | Index | Consistency | |---|---|---| | Account | `NAME` | Eventually consistent | | Account | `CODE` | Eventually consistent. Strongly consistent when an `eq` filter is supplied | | Account | `STATUS` | Eventually consistent | | AccountSet | `NAME` | Eventually consistent | | AccountSet | `CODE` | Eventually consistent. Strongly consistent when an `eq` filter is supplied | | AccountSet | `members` (`MEMBER_ID`) | Eventually consistent. Strongly consistent when both `accountSetId` and `memberId` use `eq` filters | ### Sharded Indexes Sharded indexes in Twisp provide a mechanism to enhance write scalability for partitions that experience high write throughput. By splitting a single partition into multiple shards, write operations can be distributed across these shards, thereby increasing the overall write capacity for that partition key. Each shard within a sharded partition acts like a mini-partition, handling a portion of the write load. This is similar to RAID-style disk striping, where data is divided across multiple disks to improve performance. In the context of Twisp indexes, sharding allows the system to handle more writes per second for a given partition key by parallelizing the write operations across the shards. However, this increased write capacity comes at the cost of global sort order within the partition. Since the data is distributed across multiple shards, maintaining a strict sort order across the entire partition becomes challenging. Therefore, while sharded indexes are excellent for scenarios requiring high write throughput, they may not be suitable for use cases that rely heavily on sorted data retrieval across the entire partition. To configure a sharded index, you can specify the `partition_shard_count` parameter when creating or updating an index. This parameter determines the number of shards into which each unique partition key is split. For example, setting `partition_shard_count` to 4 will divide each partition into four shards, potentially allowing for up to four times the write throughput compared to a non-sharded partition. Sharded indexes are particularly useful in scenarios where a single partition key experiences a high volume of write operations, which could otherwise lead to write throttling or performance bottlenecks. By distributing the write load, sharded indexes help maintain system responsiveness and throughput. However, it’s important to carefully consider the impact on read operations and sort order before implementing sharded indexes. ### OpenSearch Schemas For search indexes, Twisp provides full control of the underlying OpenSearch schema, including the selection of fields or expressions to be indexed and their respective data types. ## Zero-Downtime Migrations Twisp's migration infrastructure allows for online creation and modification of indexes with zero downtime. This capability ensures that updates and changes to the data schema can be implemented seamlessly, without disrupting service availability. This system allows re-partitioning of indexes on the fly, ensuring that your system remains responsive and available even during significant changes. ## Index Operations - [`Query.schema.index()`](https://www.twisp.com/docs/reference/graphql/queries.md#schema.index): Query an Index - [`Query.schema.indexes()`](https://www.twisp.com/docs/reference/graphql/queries.md#schema.indexes): Query Indexes - [`Mutation.schema.createIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#schema.create-index): Create a Custom Index - [`Mutation.schema.createHistoricalIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#schema.create-historical-index): Create a Historical Index - [`Mutation.schema.createSearchIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#schema.create-search-index): Create a Search Index - [`Mutation.schema.deleteIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#schema.delete-index): Create an Index - [`Mutation.schema.updateSearchIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#schema.update-search-index): Update a Search Index --- # Journals Reference for the journal resource within a Twisp Ledger. ## The Basics Journals are an essential part of accounting systems, as they provide a way to organize and record transactions within separate "books". > **Note:** > > Put simply, journals help you keep your financial transactions organized in **separate collections**. In Twisp, every ledger instance starts with a **default journal**. You can create additional journals as needed to suit your specific accounting structure. ## Components of Journals 1. **Name**: should be self-descriptive and helps in recognizing the journal's purpose. 2. **Status**: can be either `ACTIVE` or `LOCKED`. Journals with a `LOCKED` status do not allow transactions to be posted to them. 3. **Code**: is an optional unique code for the journal, which can be used as an additional reference. Journals also have **Created & Updated Timestamps** as well as a **Version & History**. ## Use Cases for Multiple Journals Having multiple journals can be beneficial in various scenarios. For example, users may create separate journals for different currencies or product-specific journals. By using multiple journals, you can more effectively organize transactions and maintain a clear understanding of your financial activities. ## Journal Operations Use GraphQL queries and mutations to read, create, update, and delete (lock) journals: - [`Query.journal()`](https://www.twisp.com/docs/reference/graphql/queries.md#journal): Get a single journal. - [`Query.journals()`](https://www.twisp.com/docs/reference/graphql/queries.md#journals): Query journals using index filters. - [`Mutation.createJournal()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-journal): Create a new journal. - [`Mutation.updateJournal()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-journal): Update select fields for an existing journal. - [`Mutation.deleteJournal()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-journal): Soft delete (lock) a specified journal. ## Further Reading To learn the basics of managing journals, see the tutorial on [Working With Journals](https://www.twisp.com/docs/tutorials/working-with-journals.md). To review the GraphQL docs for the `Journal` type, see [Journal](https://www.twisp.com/docs/reference/graphql/types/object.md#journal). --- # Key Values Ledger Reference for transactional key/value records in a Twisp ledger. ## The Basics The Key Values (KV) Ledger provides transactional key/value storage for arbitrary structured documents in the Twisp ledger database. Each record is addressed by a natural key made from `(namespace, key)`, where `namespace` groups related records and `key` identifies one record within that namespace. KV records are useful for application state that should live beside ledger data with the same consistency model, such as feature flags, workflow checkpoints, product configuration, integration state, or lookup documents. They are not a replacement for accounting records: money movement should still be modeled with transactions, entries, balances, and tran codes. Like other Twisp records, KV records are versioned. Creating a record starts at `version` 1. Replacing the record writes a new version, preserves `created`, updates `modified`, and makes the latest version visible through current queries. ## Components of KV Records A KV record has the following fields: 1. **Namespace**: a logical grouping key. Namespaces can be used for broad categories such as `flags`, `integrations`, or `workflow-state`. 2. **Key**: the required unique key within the namespace. The `(namespace, key)` pair identifies the current record. 3. **Description**: an optional text field stored with the record. If omitted in GraphQL input, it is stored as an empty string. 4. **Value**: a strongly-typed `Value` document. Scalars like `UUID`, `Decimal`, `Money`, `Date`, and `Timestamp` round-trip with their type intact rather than being coerced into strings or numbers. See [Strong Typing](https://www.twisp.com/docs/reference/ledger/kv.md#strong-typing) for details. 5. **Conditions**: the CEL conditions (if any) that were required to evaluate to `true` before this version of the record was written. Stored as a map of `{name: expression}` pairs for auditing. 6. **Created and Modified Timestamps**: `created` is preserved across updates, while `modified` changes when a new version is written. 7. **Version and Record ID**: `version` identifies the current record version and `_recordId` identifies the underlying Twisp record. 8. **History**: previous versions are available through the `history` field on `KVValue`. The KV Ledger enforces these limits: | Field | Limit | |-------------------|---------------------------------------------------------------------------| | `namespace` | 512 UTF-8 bytes | | `key` | 512 UTF-8 bytes | | persisted payload | 256 KiB, measured as `description` bytes plus the serialized `value` | > **Note:** > > The default KV index is partitioned by `namespace` and each `namespace` has a throughput cap of 1000 Write Units/Second and 3000 Read Units/Second. ## Writing Values Use `Mutation.kv.put()` to create or replace a record. A put for a new `(namespace, key)` pair creates version 1. A put for an existing pair writes the next version. ```graphql mutation PutKv { kv { put( input: { namespace: "flags" key: "feature-a" description: "Crypto transfer V2 rollout" value: { group: "a", enabled: true, rollout: 25, owner: "risk", code: "CRYPTO_TRANSFER_V2" } } ) { namespace key description value version } } } ``` Every `put` writes a new version. To make a write idempotent or contingent on the record's current state, use `conditions` (see [Conditional Writes](https://www.twisp.com/docs/reference/ledger/kv.md#conditional-writes)). ## Strong Typing KV values are strongly typed. The `value` field is a [`Value`](https://buf.build/twisp/api/docs/8ce263d536164f4ca8ea7311df5a5e6c%3Atwisp.type.v1#twisp.type.v1.Value) document, so scalars like `UUID`, `Decimal`, `Money`, `Date`, and `Timestamp` round-trip with their type intact instead of being coerced into strings or numbers. Reading a stored UUID back yields a UUID, not a string that happens to look like one. The mutation below writes a record whose `value.id` is a `UUID`, then captures the stored `value` into the `$val` variable using the `@export` directive so the same request can feed it back into `evaluate` and confirm that the original UUID identity is preserved end-to-end. (`@export(as: "name")` assigns the decorated field's value to the named query variable, making it available to later operations in the same request.) ```graphql mutation DemonstrateValueTyping( $id: UUID = "106c3332-08a4-4ee3-a7dd-77411882a790" $val: Value = "" ) { kv { put( input: { namespace: "flags" key: "type-roundtrip" value: { id: $id } } ) { value @export(as: "val") } } evaluate( expressions: { val: "document.val.id == uuid('106c3332-08a4-4ee3-a7dd-77411882a790')" } document: { val: $val, id: $id } ) } ``` For the underlying gRPC definitions, see: - [`twisp.type.v1.Value`](https://buf.build/twisp/api/docs/8ce263d536164f4ca8ea7311df5a5e6c%3Atwisp.type.v1#twisp.type.v1.Value): the strongly-typed value used for KV payloads. - [`twisp.core.v1.KVValue`](https://buf.build/twisp/api/docs/main%3Atwisp.core.v1#twisp.core.v1.KVValue): the KV record message. - [`twisp.core.v1.KVService`](https://buf.build/twisp/api/docs/main%3Atwisp.core.v1#twisp.core.v1.KVService): the gRPC interface for reading and writing KV records. ## Updating Values Use `Mutation.kv.update()` to evolve an existing record without sending a full replacement value. An update evaluates a patch against the existing KV `value`: string leaves are CEL expressions, and non-string leaves are literal patch values. Inside the `expressions` input, `document` refers to the current KV record and `value` refers to the currently stored payload under `document.value`. This means `value.rollout + 5` reads the current `document.value.rollout`. The patch is merged with [RFC 7396](https://www.rfc-editor.org/rfc/rfc7396) semantics: - Object values merge recursively. - A `null` patch value deletes that key from an object. - Arrays, scalars, and non-object values replace the target value. Updates only apply to existing records. If no record exists for the `(namespace, key)` pair, the mutation fails with `NOT_FOUND`. Pass a `description` on the update input to replace the stored description (an empty string clears it); omit the field to leave the existing description in place. ```graphql mutation UpdateKvPatch { kv { update( input: { namespace: "flags" key: "feature-a" expressions: { rollout: "value.rollout + 5" owner: null metadata: "{'changedBy': 'kv.update', 'tags': ['fixture', 'patch']}" } conditions: { current_rollout: "value.rollout == 50" } } ) { namespace key description value version } } } ``` To rename a record alongside its value patch, pass `description` on the update input: ```graphql mutation RenameKv { kv { update( input: { namespace: "flags" key: "feature-a" description: "renamed flag" expressions: { rollout: "value.rollout + 5" } } ) { namespace key description value version } } } ``` Every `update` writes a new version, even when the expressions evaluate to the current value. Use `conditions` to gate the write on the record's current state (see [Conditional Writes](https://www.twisp.com/docs/reference/ledger/kv.md#conditional-writes)). ## Conditional Writes `put`, `update`, and `delete` accept CEL `conditions` as a map keyed by condition name, where each value is a CEL expression. All conditions must evaluate to `true` before the write is applied, otherwise the request fails with `BAD_REQUEST`. Conditions see the **current** state of the record — the version about to be replaced, updated, or deleted — through the `document` and `value` variables. On successful `put` and `update`, the request's `conditions` are persisted on the written `KVValue` as an audit trail of what was required at write time. > **Note:** > > **`document` vs. `value` in KV conditions** > > Conditions evaluate with both the record header and the payload in scope: > > - **`document`** is the full [`KVValue`](https://buf.build/twisp/api/docs/main%3Atwisp.core.v1#twisp.core.v1.KVValue). Reach for it when you need record-level fields: `document.namespace`, `document.key`, `document.description`, `document.created`, `document.modified`, or the nested `document.value`. > - **`value`** is a shortcut for the payload — equivalent to `document.value`, but it skips a hop. Use it when reading payload fields: `value.rollout`, `value.enabled`, and so on. > > The same split applies anywhere else that evaluates CEL against a KV record, including custom index partitions and sort keys (see [Listing Values](https://www.twisp.com/docs/reference/ledger/kv.md#listing-values)). On `put` and `delete`, when no record exists yet for the `(namespace, key)` pair, both `document` and `value` are `null`. Use `document == null` to gate create-only writes and `document != null` to require that a record already exists. On `update`, the record is always present because `UpdateKv` fails with `NOT_FOUND` before conditions run when the record is missing. This put only succeeds when the record already exists: ```graphql mutation PutIfExists { kv { put( input: { namespace: "flags" key: "feature-a" description: "Crypto transfer V2 rollout" value: { group: "a", enabled: false, rollout: 50, owner: "risk", code: "CRYPTO_TRANSFER_V2" } conditions: { must_exist: "document != null" } } ) { namespace key value version } } } ``` Conditional writes are also useful for create-only writes: ```graphql conditions: { must_not_exist: "document == null" } ``` ## Reading Values Use `Query.kv()` to read the current record by `(namespace, key)`. If no current record exists, the field returns `null`. ```graphql query GetKv { kv(namespace: "flags", key: "feature-a") { namespace key description value version history(first: 10) { nodes { key version value } } } } ``` The `history` connection on `KVValue` returns versions newest-first. ## Listing Values Use `Query.kvs()` to list KV records through an index. The built-in namespace index lists records in one namespace. It requires `where.namespace.eq`. ```graphql query ListKvsByNamespace { kvs( index: { name: Namespace, sort: ASC } where: { namespace: { eq: "flags" } } first: 10 ) { nodes { key description value version } } } ``` Use a custom index when the read pattern is not organized by namespace. Custom KV indexes are created with `on: KV` and queried with `index: { name: Custom }`. ```graphql mutation CreateKvGroupLookupIndex { schema { createIndex( input: { name: "group_lookup" on: KV unique: false partition: [{ alias: "group", value: "string(value.group)" }] sort: [{ alias: "key", value: "string(document.key)", sort: ASC }] constraints: { hasGroup: "has(value.group)" } } ) { name on unique } } } ``` ```graphql query ListKvsByCustomIndex { kvs( index: { name: Custom, sort: ASC } where: { custom: { index: "group_lookup" partition: [{ alias: "group", value: { eq: "a" } }] sort: [{ alias: "key", value: { gte: "" } }] } } first: 10 ) { nodes { key description value version } } } ``` ## Deleting Values Use `Mutation.kv.delete()` to delete the current record for a `(namespace, key)` pair. The mutation returns the deleted record when one existed, otherwise it returns `null`. ```graphql mutation DeleteKv { kv { delete(namespace: "flags", key: "feature-a") { namespace key description value } } } ``` Delete also accepts CEL `conditions` that run against the current record before the delete is applied. `document` and `value` bind to the current record, or to `null` when no record exists — so `document != null` gates a delete on the record already existing, and `document.value.state == 'archived'` gates on a specific payload state. ```graphql mutation DeleteKvIfArchived { kv { delete( namespace: "flags" key: "feature-a" conditions: { only_if_archived: "document.value.state == 'archived'" } ) { namespace key } } } ``` After deletion, `Query.kv()` returns `null` for that `(namespace, key)`, and namespace or custom-index lists no longer include the deleted record. ## Combining KV Operations in One Request Only top-level mutation fields are executed sequentially by GraphQL. The fields *inside* a single `kv { ... }` selection are ordinary object sub-fields and run **in parallel**, so they can't see each other's writes. A `put` followed by an `update` in the same `kv { ... }` block will race: the `update` queries at the same time the `put` runs and sees no record, and the whole transaction aborts with `NOT_FOUND`. To run multiple KV operations against the same record in a single request, give each its own top-level `kv { ... }` selection with a field alias: ```graphql mutation PutThenUpdate { created: kv { put(input: { namespace: "flags", key: "feature-a", value: { rollout: 25 } }) { version } } incremented: kv { update( input: { namespace: "flags" key: "feature-a" expressions: { rollout: "value.rollout + 5" } } ) { version value } } } ``` Because `created` and `incremented` are top-level mutation fields, GraphQL executes them in order — the `put` finishes writing to the shared request transaction before the `update` runs its lookup. Aliased sub-fields inside one `kv { ... }` block are only safe when the operations are independent (different records, or all inserts of distinct keys). ## Real World Examples ### Feature Flag Rollout Because KV records share the same consistency model and read path as the rest of the ledger, they make a natural place to keep small operational knobs that need to be consulted inside the same request as a write. A common pattern is to use a KV record as a feature flag that controls which code a transaction posts under, so a new code can be rolled out gradually without redeploying. The flag itself is a normal KV record. Its `value` carries the rollout percentage and the candidate code, exactly matching the shape used in the [Writing Values](https://www.twisp.com/docs/reference/ledger/kv.md#writing-values) example: ```json { "group": "a", "enabled": true, "rollout": 25, "owner": "risk", "code": "CRYPTO_TRANSFER_V2" } ``` The mutation below reads the flag inside the same request that posts the transaction. The `@export` directive evaluates a CEL expression against the stored `value`: when a uniformly distributed roll falls under `document.rollout`, the new `code` from the flag is exported into `$code`; otherwise the caller-supplied default is kept. The `postTransaction` call then uses whichever code was selected. ```graphql # posts using `CRYPTO_TRANSFER_V1` or `CRYPTO_TRANSFER_V2` based on flag. mutation PostTransactionFromFeatureFlag( $ns: String = "flags" $key: String = "feature-a" $transactionId: UUID = "23872efc-39c6-11f1-a5bd-069b540ea27b" $code: String = "CRYPTO_TRANSFER_V1" $params: JSON = "{}" ) { queries { kv(namespace: $ns, key: $key) { value @export( as: "code" cel: "rand.Intn(100) < document.rollout ? document.code : context.vars.code" ) } } postTransaction( input: { transactionId: $transactionId tranCode: $code params: $params } ) { transactionId } } ``` This pattern works because the KV read, the CEL evaluation, and the transaction post all happen inside one transactional request: there is no window in which the flag could change between the lookup and the post, and the rollout decision is recorded in the same audit trail as the transaction it produced. Updating the rollout percentage or the target code is a single `Mutation.kv.put()` away, and pairing it with the [Conditional Writes](https://www.twisp.com/docs/reference/ledger/kv.md#conditional-writes) pattern keeps concurrent edits to the flag safe. ### Tokenized Card Vault KV records are also useful for storing typed references - like a card token paired with its expiration - under a per-customer namespace. Addressing the record as `customer001.cards:card001` gives the rest of the system a stable handle to look the card up by, without standing up a bespoke table for each kind of reference. Because [`Value` is strongly typed](https://www.twisp.com/docs/reference/ledger/kv.md#strong-typing), the `UUID` token and `Date` expiration are stored and read back as their native types instead of being flattened into strings. The write is an ordinary put. The variables flow straight into `value` with their declared types: ```graphql mutation WriteCardData( $cardNamespace: String! = "customer001.cards" $cardKey: String! = "card001" $cardToken: UUID! = "8f3b2a01-1c4d-4e7a-9b62-2c71f3d44a01" $cardExpiration: Date! = "2026-01-01" ) { kv { put( input: { namespace: $cardNamespace key: $cardKey value: { cardToken: $cardToken cardExpiration: $cardExpiration } } ) { namespace key } } } ``` Reading the card back and using it inside the same request follows the same shape as the [Feature Flag Rollout](https://www.twisp.com/docs/reference/ledger/kv.md#feature-flag-rollout) example. Aliasing the `value` field lets the same selection be exported twice with different `cel` projections, so each typed field lands in its own variable: ```graphql mutation UseCardData( $cardNamespace: String! = "customer001.cards" $cardKey: String! = "card001" $transactionId: UUID! = "8a4ec2ee-9d3e-4f1a-9c82-ab12cd34ef56" $cardToken: UUID $cardExpiration: Date ) { queries { kv(namespace: $cardNamespace, key: $cardKey) { cardToken: value @export(as: "cardToken", cel: "document.cardToken") cardExpiration: value @export(as: "cardExpiration", cel: "document.cardExpiration") } } postTransaction( input: { transactionId: $transactionId tranCode: "CARD_AUTH" params: { cardToken: $cardToken cardExpiration: $cardExpiration } } ) { transactionId } } ``` `$cardToken` and `$cardExpiration` keep their `UUID` and `Date` types end to end — from the stored `value`, through the CEL projection, into the `postTransaction` call — without any string parsing in between. ## KV Operations Use GraphQL queries and mutations to read, write, list, and delete KV records: - [`Query.kv()`](https://www.twisp.com/docs/reference/graphql/queries.md#kv): Get the current KV record for a `(namespace, key)` pair. - [`Query.kvs()`](https://www.twisp.com/docs/reference/graphql/queries.md#kvs): List KV records by namespace or custom index. - [`KVValue.history()`](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue): Read the version history for a KV record. - [`Mutation.kv.put()`](https://www.twisp.com/docs/reference/graphql/mutations.md#kv-put): Create or replace a KV record. - [`Mutation.kv.update()`](https://www.twisp.com/docs/reference/graphql/mutations.md#kv-update): Evaluate patch expressions and merge them into an existing KV record. - [`Mutation.kv.delete()`](https://www.twisp.com/docs/reference/graphql/mutations.md#kv-delete): Delete the current KV record for a `(namespace, key)` pair. - [`Mutation.schema.createIndex()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-index): Create a custom index on `KV`. ## Further Reading For custom index design, see [Indexes](https://www.twisp.com/docs/reference/ledger/indexes.md). For record versioning and history, see [Versions And History](https://www.twisp.com/docs/reference/ledger/versions-and-history.md). To review the GraphQL docs for the `KVValue` type, see [KVValue](https://www.twisp.com/docs/reference/graphql/types/object.md#kvvalue). --- # Money Formatting Reference for money formatting options for amounts in a Twisp Ledger. ## The Basics The [Money](https://www.twisp.com/docs/reference/graphql/types/object.md#money) type in Twisp represents a monetary amount. Fields of this type can be represented (via its `formatted` field) in various ways depending on the options provided in the [MoneyFormatInput](https://www.twisp.com/docs/reference/graphql/types/input.md#money-format-input). This reference provides a review of the different ways to format monetary amounts in Twisp, including formatting whole numbers, minimum and maximum digits, rounding modes, locales, grouping, currency minimum digits, and currency displays. > **Note:** > > Unless otherwise indicated, all examples below use the `en-US` locale. ## Minor Units Setting the `minDigits` and `maxDigits` determines how many digits of the minor units to display. When `minDigits` not specified, it will use the default fractional digits for the currency. | Units | Currency | Min Digits | Max Digits | Formatted | |-------------|----------|------------|------------|-------------| | 9 | USD | _DEFAULT_ | _DEFAULT_ | `$9.00` | | 9 | USD | _DEFAULT_ | 0 | `$9` | | 9 | USD | 0 | _DEFAULT_ | `$9` | | 9 | USD | 1 | _DEFAULT_ | `$9.0` | | 9 | USD | 2 | _DEFAULT_ | `$9.00` | | 9 | USD | 3 | _DEFAULT_ | `$9.000` | | 9.123456789 | USD | _DEFAULT_ | _DEFAULT_ | `$9.123457` | | 9.123456789 | USD | _DEFAULT_ | 0 | `$9` | | 9.123456789 | USD | _DEFAULT_ | 0 | `$9.1` | | 9.123456789 | USD | _DEFAULT_ | 0 | `$9.12` | | 9.123456789 | USD | _DEFAULT_ | 0 | `$9.123` | ## Rounding The `roundingMode` option defines the rounding behavior when the fractional units exceed the `maxDigits`. | Units | Currency | Rounding Mode | Max Digits | Formatted | |-------|----------|---------------|------------|-----------| | 9.005 | USD | `DOWN` | 2 | `$9.00` | | 9.005 | USD | `HALF_DOWN` | 2 | `$9.00` | | 9.005 | USD | `UP` | 2 | `$9.01` | | 9.005 | USD | `HALF_UP` | 2 | `$9.01` | | 9.006 | USD | `DOWN` | 2 | `$9.00` | | 9.006 | USD | `HALF_DOWN` | 2 | `$9.01` | | 9.006 | USD | `UP` | 2 | `$9.01` | | 9.006 | USD | `HALF_UP` | 2 | `$9.01` | ## Currency Display Use the `currencyDisplay` to change the currency indicator. | Units | Currency | Currency Display | Formatted | |----------|----------|------------------|----------------| | 12345.67 | USD | _DEFAULT_ | `$12345.67` | | 12345.67 | USD | `CODE` | `USD 12345.67` | | 12345.67 | USD | `NONE` | `12345.67` | | 12345.67 | USD | `SYMBOL` | `$12345.67` | ## Other Locales Changing the `locale` option formats the amount according to the standards of that locale. | Units | Currency | Locale (Country) | Formatted | |---------------------|----------|--------------------|------------------------| | 123456789.123456789 | USD | `zh-CN` (China) | `US$123456789.123457` | | 123456789.123456789 | USD | `es-CO` (Colombia) | `US$ 123456789,123457` | | 123456789.123456789 | USD | `fr-FR` (France) | `123456789,123457 $US` | | 123456789.123456789 | USD | `de-DE` (Germany) | `123456789,123457 $` | | 123456789.123456789 | USD | `hi-IN` (India) | `$123456789.123457` | | 123456789.123456789 | USD | `ja-JP` (Japan) | `$123456789.123457` | | 123456789.123456789 | USD | `ar-AE` (UAE) | `US$ 123456789.123457` | | 123456789.123456789 | USD | `en-GB` (UK) | `US$123456789.123457` | | 123456789.123456789 | USD | `en-US` (USA) | `$123456789.123457` | | 123456789.123456789 | EUR | `zh-CN` (China) | `€123456789.123457` | | 123456789.123456789 | EUR | `es-CO` (Colombia) | `€ 123456789,123457` | | 123456789.123456789 | EUR | `fr-FR` (France) | `123456789,123457 €` | | 123456789.123456789 | EUR | `de-DE` (Germany) | `123456789,123457 €` | | 123456789.123456789 | EUR | `hi-IN` (India) | `€123456789.123457` | | 123456789.123456789 | EUR | `ja-JP` (Japan) | `€123456789.123457` | | 123456789.123456789 | EUR | `ar-AE` (UAE) | `€ 123456789.123457` | | 123456789.123456789 | EUR | `en-GB` (UK) | `€123456789.123457` | | 123456789.123456789 | EUR | `en-US` (USA) | `€123456789.123457` | ## Grouping When `groupDigits` is set to `true`, digits will be grouped according to the standards for each locale. | Units | Currency | Locale (Country) | Formatted | |---------------------|----------|--------------------|--------------------------| | 123456789.123456789 | USD | `zh-CN` (China) | `US$123,456,789.123457` | | 123456789.123456789 | USD | `es-CO` (Colombia) | `US$ 123.456.789,123457` | | 123456789.123456789 | USD | `fr-FR` (France) | `123 456 789,123457 $US` | | 123456789.123456789 | USD | `de-DE` (Germany) | `123.456.789,123457 $` | | 123456789.123456789 | USD | `hi-IN` (India) | `$12,34,56,789.123457` | | 123456789.123456789 | USD | `ja-JP` (Japan) | `$123,456,789.123457` | | 123456789.123456789 | USD | `ar-AE` (UAE) | `US$ 123,456,789.123457` | | 123456789.123456789 | USD | `en-GB` (UK) | `US$123,456,789.123457` | | 123456789.123456789 | USD | `en-US` (USA) | `$123,456,789.123457` | ## Minimum Digits by Currency The default setting for `minDigits` changes depending on which currency is used because different currencies have a different number of minor units used. - US dollars (`USD`) use 2 minor units (i.e. cents). - Jordanian Dinars (`JOD`) use 3 minor units. - Uganda Shillings (`UGX`) use no minor units. `UGX` is the code for the Uganda shilling, which uses 0 minor units. | Units | Currency | Formatted | |-------|----------|-------------| | 9 | USD | `$9.00` | | 9 | JOD | `JOD 9.000` | | 9 | UGX | `UGX 9` | --- # Transaction Codes Reference for the tran code resource within a Twisp Ledger. ## The Basics Transaction codes (AKA "tran codes") define how ledger entries are written in Twisp. You can think of them as macros or templates for transactions; instead of writing out every transaction by hand within your application layer, you design the tran codes to match every type of transaction in your funds flow. > **Note:** > > In a nutshell, transaction codes **accept input values** and **write a multi-entry transaction to the ledger**. In this way, tran codes form a _self-documenting API for your funds flow_. The benefits of this approach are legion: - Strong separation of concerns between accounting logic (i.e. how ledger entries need to be written to which accounts) and product/business logic. - All transactions are executed atomically. Enforcing all-or-nothing commits leads to correct and easy-to-reason-about systems. - Centralized interface for defining every type of transactional activity that your system handles, providing a rich view into your funds flow. - A linear—not exponential—growth curve in system complexity as more and more transaction types are added to reflect the growth of your financial product. With tran codes as the mechanism for structuring your transactions, you can reign in your funds flow and prevent it from becoming a tangled and unmanageable mess. ## Components of Tran Codes There are 4 primary components which define a tran code: 1. **Code**: a unique name to identify the tran code, usually formatted in UPPER_SNAKE_CASE. When posting a transaction, this is the value supplied to the `tranCode` field to specify which tran code should be invoked. 2. **Params**: the definition of the parameters available when invoking a tran code. This allows values to be supplied at runtime which can be injected into the [Transaction](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) and [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) written by the tran code. 3. **Transaction**: the specification of values to be used for the [Transaction](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) written. Invoking a tran code writes a single transaction into the ledger, and the values used for that transaction are defined either as literals or else are derived from values passed in `params`. 4. **Entries:** the specification of values to be used for the ledger [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) written for the transaction when a tran code is invoked. The values used for these entries are defined either as literals or else are derived from values passed in `params`. In addition, tran codes have other properties which are common to all records in the accounting core: - **ID**: a universally unique identifier (UUID) for the tran code. - **Description**: a free-form text to be used for describing anything about the tran code. We recommend using this field to summarize what the tran code is for and when it should be used. - **Created & Updated Timestamps**: self-evident: when the tran code was created and when it was last updated. - **Version & History**: tran codes, like every other record in the accounting core, maintain a list of all changes made to them in their `history` field, and the `version` field indicates the current active version of the tran code. ## Tran Code Invocation Whenever you post a transaction in Twisp, you must supply a tran code to invoke. _There is no way to post transactions outside of a tran code invocation._ In this sense, posting a transaction is how you invoke a tran code. One cannot happen without the other. Posting a transaction requires only three components: a `transactionId` to ensure idempotency for the transaction, the `tranCode` identifier matching the `code` field of the tran code to invoke, and the `params` object to provide parameter values for the tran code. **Request** ```graphql mutation PostACHCredit( $userAcctId: UUID! $amount: String! $effective: String! ) { postTransaction( input: { transactionId: "66fcf002-f815-4608-ad38-8455a46d7f02" tranCode: "ACH_CREDIT" params: { account: $userAcctId, amount: $amount, effective: $effective } } ) { transactionId tranCode { code } effective entries(first: 2) { nodes { amount { money: formatted(as: { locale: "en-US" }) } direction layer account { name } } } } } ``` **Response** ```json { "data": { "postTransaction": { "transactionId": "66fcf002-f815-4608-ad38-8455a46d7f02", "tranCode": { "code": "ACH_CREDIT" }, "effective": "2022-10-02", "entries": { "nodes": [ { "amount": { "money": "$9.53" }, "direction": "DEBIT", "layer": "SETTLED", "account": { "name": "ACH Settlement" } }, { "amount": { "money": "$9.53" }, "direction": "CREDIT", "layer": "SETTLED", "account": { "name": "Example Acct" } } ] } } } } ``` **Variables** ```json { "amount": "9.53", "effective": "2022-10-02", "userAcctId": "fcb5a92f-cafb-4076-93dd-5df6d759a482" } ``` The above example will write a [Transaction](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction) and [Entries](https://www.twisp.com/docs/reference/graphql/types/object.md#entry) as defined in the `ACH_CREDIT` tran code, using the parameters supplied. ## Tran Code Operations Use GraphQL queries and mutations to read, create, update, and delete (lock) tran codes: - [`Query.tranCode()`](https://www.twisp.com/docs/reference/graphql/queries.md#tran-code): Get a single tran code. - [`Query.tranCodes()`](https://www.twisp.com/docs/reference/graphql/queries.md#tran-codes): Query tran codes using index filters. - [`Mutation.createTranCode()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-tran-code): Create a new transaction code. - [`Mutation.updateTranCode()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-tran-code): Update select fields for an existing transaction code. - [`Mutation.deleteTranCode()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-tran-code): Soft delete (lock) a specified transaction code. ## Further Reading To learn how to work with tran codes, see the relevant tutorials on [Building Tran Codes](https://www.twisp.com/docs/tutorials/building-tran-codes.md) and [Designing Tran Codes](https://www.twisp.com/docs/tutorials/advanced/designing-tran-codes.md). For more context on how and why Twisp uses tran codes, see [Encoded Transactions](https://www.twisp.com/docs/accounting-core/encoded-transactions.md). To review the GraphQL docs for the `TranCode` type, see [TranCode](https://www.twisp.com/docs/reference/graphql/types/object.md#tran-code). --- # Transactions Reference for the transaction resource within a Twisp Ledger. ## The Basics Transactions in Twisp record all accounting events in the ledger, utilizing transaction codes to automate and categorize entries. Through tran codes, Twisp automates and categorizes ledger entries, streamlining the accounting process and ensuring consistency. > **Note:** > > Transactions capture all **financial activities** and leverage tran codes to maintain a well-organized and accurate ledger. Transactions in Twisp... - Utilize double-entry accounting principles (ensures that the debit and credit entries balance out) - Ensure atomic, all-or-nothing commits for predictable and error-resistant ledgering - Leverage transaction codes (tran codes) to automate and categorize entries - Maintain a complete history of all changes to records ## Components of Transactions There are 5 primary components which make up a transaction: 1. **Entries**: written to the ledger by this transaction. 2. **Journal**: in which the transaction is posted. 3. **Tran Code**: provides a reference to the tran code used when posting this transaction. 4. **Effective**: date when the transaction is recorded as occurring for accounting purposes. 5. **Correlated**: transactions connect related transactions together, providing context and improving traceability within the ledger. In addition, transactions have other properties which are common to most or all resources in the accounting core: - **ID**: a universally unique identifier (UUID) for the transaction. - **Description**: a free-form text to be used for describing anything about the transaction. - **Metadata**: unstructured, user-specified JSON. Can be combined with custom indexes for powerful querying capacities. - **Created & Updated Timestamps**: self-evident: when the transaction was created and when it was last updated. - **Version & History**: transactions, like every other record in the accounting core, maintain a list of all changes made to them in their `history` field, and the `version` field indicates the current active version of the transaction. ## Transaction Operations Use GraphQL to query, post, and update transactions: - [`Query.transaction()`](https://www.twisp.com/docs/reference/graphql/queries.md#transaction): Get a single transaction. - [`Query.transactions()`](https://www.twisp.com/docs/reference/graphql/queries.md#transactions): Query transactions using index filters. - [`Mutation.postTransaction()`](https://www.twisp.com/docs/reference/graphql/mutations.md#post-transaction): Post a transaction to the ledger using a specified tran code. - [`Mutation.updateTransaction()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-transaction): Update select fields for a posted transaction. ## Further Reading To learn the basics of posting transactions, see the tutorial on [Posting Transactions](https://www.twisp.com/docs/tutorials/posting-transactions.md). For more context on why Twisp structures transactions with tran codes, see [Encoded Transactions](https://www.twisp.com/docs/accounting-core/encoded-transactions.md). To review the GraphQL docs for the `Transaction` type, see [Transaction](https://www.twisp.com/docs/reference/graphql/types/object.md#transaction). --- # Velocity Controls Reference for the Velocity Control resources within a Twisp ledger. ## The Basics Velocity Controls in the Twisp Accounting Core provide a mechanism to define and enforce restrictions on the flow of transactions and balances within accounts and account sets. These controls are essential for managing financial governance, ensuring compliance, and mitigating risks by setting specific limits on account activities. ## Components of a Velocity Control A Velocity Control is made up of two main components: - **Velocity Control**: Defines the enforcement actions when one or more Velocity Limits are violated. - **Velocity Limit**: Defines a balance and a parameterizable limit that is enforced. This balance can occur across a number of dimensions. Once a Velocity Control is defined, it may be **attached** to accounts and/or account sets to begin enforcing the defined limits for those accounts or sets. If during the posting of a transaction, an attached Velocity Control is violated an exception will be generated and depending on the enforcement configuration, the transaction will be rejected, voided or warned. ### Velocity Control There are 3 key components that make up a Velocity Control 1. **Enforcement**: A Velocity Control can define it's enforcement mechanism, there are three `WARN`, `VOID` and `REJECT`. This defines whether the violated entry is written to the ledger and how the ledger will respond to the violating entry. 2. **Velocity Limits**: The Velocity Limits on a control define one or more balances that are under enforcement of a particular control. These balances can contain windowing and filtering criteria to keep track of different types of balances that will be enforced on by the Velocity Control. 3. **Condition**: A CEL expression which evaluates to a boolean value allows for fine grained control to determine if the Velocity Control will execute enforcement. For example, a Velocity Limit may be exceeded, but the control only enforces `PENDING` transactions. ### Velocity Limits Velocity Limits form the foundation of Velocity Controls. They specify the maximum allowable balance or transaction volume over a defined period. Each Velocity Limit is tailored to control spending, deposits, or any financial activity based on parameters like amount, currency, and account layers (SETTLED, PENDING, ENCUMBRANCE). By enforcing these limits, organizations ensure that financial activities remain within predefined thresholds, maintaining financial discipline and control. There are 5 key components of a Velocity Limit: 1. **Window**: Every Velocity Limit has a default set of dimensions (currency, journal, account) and this `window` can define additional dimensions, such as bucketed time periods or values from account or entry metadata. 2. **Limit**: The limit to apply, which currently only supports an available balance limit. This defines the layer, amount, and normal balance type that the limit supports. 3. **Condition**: A CEL expression which evaluates to a boolean value for filtering if an entry is eligible to apply to the limit. For example if a limit is only applied to a certain category of transactions defined in transaction metadata. 4. **Currency**: Defines which currency the limit applies to. 5. **Params**: The definition of the parameters available when attaching a a limit used in a Velocity Control to an account. This allows values to supplied at attachment time so that a Velocity Control can have different enforced limits for different accounts. ### Attaching Velocity Controls Attaching a Velocity Control to an Account or Set enables that Account or Set to begin enforcing entries that are posted. There are three components to an attachment: 1. **Velocity Control Id**: Identifies the particular Velocity Control to attach. 2. **Account or Set Id**: The account or set to attach control to. 3. **Params**: A JSON set of parameters that satisfies all the defined parameters on the limits attached to the controls. > **Note:** > > When defining parameters on Velocity Limits use _unique parameter names_ to avoid collisions between parameters. ### Overriding Velocity Control Enforcement Velocity Control enforcement can be escalated or de-escalated for a control with an action configured at the `VOID` or `REJECT` level, by passing the `overrideVelocityEnforcement` parameter on [postTransaction](https://www.twisp.com/docs/reference/graphql/mutations.md#post-transaction). This is useful for setting to `WARN` for force post transactions that require disabled velocity control enforcement. ## Velocity Control Operations Use GraphQL queries and mutations to read, create, delete and attach Velocity Controls and limits: - [`Query.velocityControl()`](https://www.twisp.com/docs/reference/graphql/queries.md#velocity-control): Get a single Velocity Control - [`Query.velocityControls()`](https://www.twisp.com/docs/reference/graphql/queries.md#velocity-controls): Query Velocity Controls - [`Query.velocityLimit()`](https://www.twisp.com/docs/reference/graphql/queries.md#velocity-limit): Get a single Velocity Limit - [`Query.velocityLimits()`](https://www.twisp.com/docs/reference/graphql/queries.md#velocity-limits): Query Velocity Limits - [`Mutation.createVelocityControl()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-velocity-control): Create a Velocity Control - [`Mutation.updateVelocityControl()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-velocity-control): Update a Velocity Control - [`Mutation.deleteVelocityControl()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-velocity-control): Delete a Velocity Control - [`Mutation.createVelocityLimit()`](https://www.twisp.com/docs/reference/graphql/mutations.md#create-velocity-limit): Create a Velocity Limit - [`Mutation.updateVelocityLimit()`](https://www.twisp.com/docs/reference/graphql/mutations.md#update-velocity-limit): Update a Velocity Limit - [`Mutation.deleteVelocityLimit()`](https://www.twisp.com/docs/reference/graphql/mutations.md#delete-velocity-limit): Delete a Velocity Limit - [`Mutation.attachControl()`](https://www.twisp.com/docs/reference/graphql/mutations.md#attach-velocity-control): Attach Velocity Control to an Account or Account Set - [`Mutation.detachControl()`](https://www.twisp.com/docs/reference/graphql/mutations.md#detach-velocity-control): Detach Velocity Control from Account or Account Set --- # Versions and History Every record in a Twisp ledger maintains a full history of all changes applied to it. All previous versions of a record can be queried. ## The Basics Record versioning and history is the foundation of [append-only immutability](https://www.twisp.com/docs/infrastructure/ledger-database.md#append-only-immutability) in the Twisp Accounting Core. All data entering the Twisp system is written as a new data record that cannot be modified. Prohibiting modification or deletion of data ensures a complete log of all changes to the system, allowing for auditable data history. > **Note:** > > Append-only immutability is the only data storage model in the Twisp Accounting Core and cannot be disabled. ## Record Versioning Twisp stores all data within records in the storage system. Each record is assigned a unique record ID. The indexing system provides pointers to records for specific keys. For example, an `accountId` index points to the specific corresponding `account` record. The first version of a new record is assigned `version` 1. When any operation needs to modify that record, a second record is written with the same unique record ID, but with `version` now set to 2. This pattern repeats indefinitely for every record in the system. > **Note:** > > For a particular record, version numbers form a consecutive integer sequence. Each new version number is exactly one greater than the previous version number. In addition to the `version` number, each record version contains a number of useful timestamps: 1. `created`: the time the transaction began that created the first record version. 2. `modified`: the time the transaction began that wrote the record version. If version is 1, `modified` is equal to the `created` timestamp. 3. `committed`: the time the transaction committed that wrote the record version. ## Version History All record versions are queryable via the `history` API available on every object in the system. This allows for retrospective analysis, auditing, and verification of data changes over time. ## Point-in-time Queries In addition to scanning an entire record version history, Twisp provides the ability to return versions active at specific point-in-time. By specifying timestamps in the `history` API `where` filter, version history can be filtered by either the `modified` or `committed` record version timestamps. **Request** ```graphql query GetPointInTimeHistory( $journalGLId: UUID! $accountCardSettlementId: UUID! ) { balance( accountId: $accountCardSettlementId journalId: $journalGLId currency: "USD" ) { history( first: 1 where: { modified: { lt: "2030-04-05T17:45:55.347145Z" } } ) { nodes { version available(layer: SETTLED) { normalBalance { formatted(as: { locale: "en-US" }) } } } } } } ``` **Response** ```json { "data": { "balance": { "history": { "nodes": [ { "version": 3, "available": { "normalBalance": { "formatted": "-$4.53" } } } ] } } } } ``` **Variables** ```json { "journalGLId": "822cb59f-ce51-4837-8391-2af3b7a5fc51", "accountCardSettlementId": "a9c8dde6-c0e5-407c-9d99-029c523f7ea8" } ``` --- # Warehouse Reference for the data warehouse of Twisp ledgers. ## The Basics The Twisp ledger exports all data to AWS Redshift and exposes APIs to interact with the data using arbitrary SQL queries. When enabled on your tenant, this warehouse provides a convenient way to execute analytical queries or unload data to your own data lake or warehouse. > **Note:** > > **Tip:** If you need to export data in bulk, you can use the [export API](https://www.twisp.com/docs/tutorials/advanced/export-data.md) without having warehouse enabled. ## Components of Warehouse ### GraphQL Interface Twisp exposes the [Redshift Data API](https://docs.aws.amazon.com/redshift-data/latest/APIReference/Welcome.html) in GraphQL format for execution of SQL queries. The most commonly used API interactions are described here. #### Execute Statement The execute statement API allows you to execute a statement on Redshift. ```graphql mutation ExecuteStatement($SQL:String! = "SELECT TRUE") { warehouse{ executeStatement(input:{ SQL: $SQL }) { id } } } ``` #### Describe Statement Describe Statement allows you to check on the status of a running query and retrieve metadata about it's results. ```graphql query DescribeStatement($id:String!) { warehouse{ describeStatement(input:{ id:$id }) { resultRows resultSize status error } } } ``` #### Cancel Statement Cancel statement cancels a running statement. ```graphql mutation CancelStatement($id:String!) { warehouse{ cancelStatement( input:{ id } ) } } ``` #### Get Statement Result Get Statement Result allows you to fetch the results of a query via the API with paging. If the result is particularly large, you may opt to instead use the [UNLOAD capabilty](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html) to export data in a suitable format to an S3 bucket of your choosing. ```graphql query GetStatementResult($id:String!) { warehouse{ getStatementResult(input:{ id:$id #nextToken:"" }) { records { fields { type value { str bytes isNull } } } nextToken } } } ``` ### Views and Schemas Twisp maintains two views for each entity in the ledger: - **`entity`**: the latest version of any entity stored in the Twisp ledger. - **`entity_history`**: all versions of a particular record stored in the Twisp ledger. Each record contains a number of header rows prepended with `record_`: - `record_begin` - A unique timestamp of when the Twisp database transaction began. - `record_rowid` - A uuid identifier of the particular item in Twisp. - `record_status` - An enumeration indicating whether this record is deleted. - `record_tenantid` - A uuid indicating the tenant that this record belongs to. - `record_version` - An monotonically increasing unsigned integer indicating the version of the record. These columns allow for incremental exports via `record_begin`, which are guaranteed to be unique per transaction. In other words, records with the same timestamp originated within the same transaction. The `record_rowid` and `record_version` together uniquely identify a particular version of a record and is a convenient way to de-duplicate rows in the event you use overlapping timestamps to import data. The following entities are available in the warehouse: - `public.account` - `public.account_history` - `public.account_set` - `public.account_set_history` - `public.account_set_member` - `public.account_set_member_history` - `public.balance` - `public.balance_history` - `public.calculation` - `public.calculation_history` - `public.entry` - `public.entry_history` - `public.journal` - `public.journal_history` - `public.tran_code` - `public.tran_code_history` - `public.transaction` - `public.transaction_history` - `public.transaction_exception` - `public.transaction_exception_history` - `public.workflow_execution` - `public.workflow_execution_history` The schemas between each `entity` and `entity_history` view are identical and are provided below. #### account Every Account and Account Set in Twisp has an account record stored. | Column Name | Type | |----------------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `account_id`| `VARCHAR(36)`| | `status`| `VARCHAR`| | `name`| `SUPER`| | `code`| `VARCHAR`| | `normal_balance_type`| `VARCHAR`| | `description`| `SUPER`| | `metadata`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `external_id`| `VARCHAR`| | `config_enable_concurrent_posting`| `BOOLEAN`| | `config_is_account_set`| `BOOLEAN`| #### account_set The `account_set` table has all Account Sets in the Twisp ledger. | Column Name | Type| |----------------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `account_set_id`| `VARCHAR(36)`| | `journal_id`| `VARCHAR(36)`| | `account_id`| `VARCHAR(36)`| | `name`| `VARCHAR`| | `description`| `VARCHAR`| | `metadata`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `config_enable_concurrent_posting`| `BOOLEAN`| #### account_set_member The `account_set_member` table maintains the Account Set tree membership details. The `member_id` can refer to _either_ an Account Set or Account, based on `member_type`. | Column Name | Type| |-----------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `account_set_id`| `VARCHAR(36)`| | `journal_id`| `VARCHAR(36)`| | `member_type`| `VARCHAR`| | `member_id`| `VARCHAR(36)`| | `created`| `TIMESTAMP`| #### balance Contains all Balance records and versions. Note that the `dimension` column is of `VARBYTE` type. If unloading, you must convert into a base64 encoded string: ```SQL SELECT FROM_VARBYTE(dimension,'base64') AS dimension FROM balance; ``` | Column Name | Type| |----------------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `journal_id`| `VARCHAR(36)`| | `account_id`| `VARCHAR(36)`| | `transaction_id`| `VARCHAR(36)`| | `entry_id`| `VARCHAR(36)`| | `currency`| `VARCHAR`| | `settled_dr_balance`| `VARCHAR`| | `settled_cr_balance`| `VARCHAR`| | `settled_entry_id`| `VARCHAR(36)`| | `settled_modified`| `TIMESTAMP`| | `pending_dr_balance`| `VARCHAR`| | `pending_cr_balance`| `VARCHAR`| | `pending_entry_id`| `VARCHAR(36)`| | `pending_modified`| `TIMESTAMP`| | `encumbrance_dr_balance`| `VARCHAR`| | `encumbrance_cr_balance`| `VARCHAR`| | `encumbrance_entry_id`| `VARCHAR(36)`| | `encumbrance_modified`| `TIMESTAMP`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `available_settled_dr_balance`| `VARCHAR`| | `available_settled_cr_balance`| `VARCHAR`| | `available_settled_entry_id`| `VARCHAR(36)`| | `available_settled_modified`| `TIMESTAMP`| | `available_pending_dr_balance`| `VARCHAR`| | `available_pending_cr_balance`| `VARCHAR`| | `available_pending_entry_id`| `VARCHAR(36)`| | `available_pending_modified`| `TIMESTAMP`| | `available_encumbrance_dr_balance`| `VARCHAR`| | `available_encumbrance_cr_balance`| `VARCHAR`| | `available_encumbrance_entry_id`| `VARCHAR(36)`| | `available_encumbrance_modified`| `TIMESTAMP`| | `calculation_id`| `VARCHAR(36)`| | `dimension`| `VARBYTE`| | `dimensions`| `SUPER`| | `entry_committed`| `TIMESTAMP`| | `entry_timestamps`| `SUPER`| #### calculation Contains the calculation definitions in the Ledger. | Column Name | Type| |------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `calculation_id`| `VARCHAR(36)`| | `description`| `VARCHAR`| | `code`| `VARCHAR`| | `dimensions`| `SUPER`| | `status`| `VARCHAR`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `condition`| `SUPER`| | `skip_calculation`| `BOOLEAN`| | `backfill_status`| `VARCHAR`| #### entry All of the journal entries in the Ledger. | Column Name | Type| |------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `entry_id`| `VARCHAR(36)`| | `transaction_id`| `VARCHAR(36)`| | `transaction_seq`| `BIGINT`| | `journal_id`| `VARCHAR(36)`| | `account_id`| `VARCHAR(36)`| | `entry_type`| `VARCHAR`| | `layer`| `VARCHAR`| | `direction`| `VARCHAR`| | `description`| `VARCHAR`| | `amount`| `VARCHAR`| | `balance_record_id`| `VARCHAR(36)`| | `balance_record_version`| `BIGINT`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `metadata`| `SUPER`| | `committed`| `TIMESTAMP`| | `parent_account_ids`| `SUPER`| | `is_voided_entry`| `BOOLEAN`| | `is_void_entry`| `BOOLEAN`| #### journal All of the journals in the Ledger. | Column Name | Type| |----------------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `journal_id`| `VARCHAR(36)`| | `name`| `VARCHAR`| | `description`| `VARCHAR`| | `status`| `VARCHAR`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `code`| `VARCHAR`| | `config_enable_effective_balances`| `BOOLEAN`| #### tran_code All of the Transaction Code definitions in the Ledger. | Column Name | Type| |----------------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `tran_code_id`| `VARCHAR(36)`| | `code`| `VARCHAR`| | `description`| `VARCHAR`| | `status`| `VARCHAR`| | `params`| `SUPER`| | `transaction_journal_id`| `SUPER`| | `transaction_correlation_id`| `SUPER`| | `transaction_external_id`| `SUPER`| | `transaction_effective`| `SUPER`| | `transaction_description`| `SUPER`| | `transaction_metadata`| `SUPER`| | `entries`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `metadata`| `SUPER`| #### transaction All of the Transactions posted in the Ledger. | Column Name | Type| |-------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `transaction_id`| `VARCHAR(36)`| | `tran_code_id`| `VARCHAR(36)`| | `journal_id`| `VARCHAR(36)`| | `correlation_id`| `VARCHAR`| | `external_id`| `VARCHAR`| | `effective`| `DATE`| | `description`| `VARCHAR`| | `metadata`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `tran_code_version`| `BIGINT`| | `void_of`| `VARCHAR(36)`| | `voided_by`| `VARCHAR(36)`| #### transaction_exception All Transaction Exceptions for `WARN` and `VOID` velocity control enforcements. | Column Name | Type| |-----------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `transaction_id`| `VARCHAR(36)`| | `type`| `VARCHAR`| | `error_message`| `VARCHAR`| | `detail`| `SUPER`| | `created`| `TIMESTAMP`| #### velocity_control All Velocity Controls defined in the ledger. | Column Name | Type| |---------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `velocity_control_id`| `VARCHAR(36)`| | `name`| `VARCHAR`| | `description`| `VARCHAR`| | `enforcement`| `SUPER`| | `condition`| `VARCHAR`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| #### velocity_limit All Velocity Limits defined in the Ledger. | Column Name | Type| |-------------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `velocity_limit_id`| `VARCHAR(36)`| | `name`| `VARCHAR`| | `description`| `VARCHAR`| | `window`| `SUPER`| | `condition`| `SUPER`| | `currency`| `VARCHAR`| | `timestamp_source`| `VARCHAR`| | `limit`| `SUPER`| | `params`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| #### workflow_execution A log of all workflow executions for `workflow.execute`. | Column Name | Type| |-----------------|-------------| | `record_begin`| `TIMESTAMP`| | `record_rowid`| `VARCHAR(36)`| | `record_status`| `VARCHAR`| | `record_tenantid`| `VARCHAR(36)`| | `record_version`| `BIGINT`| | `workflow_id`| `VARCHAR(36)`| | `execution_id`| `VARCHAR(36)`| | `task`| `VARCHAR`| | `params`| `SUPER`| | `context`| `SUPER`| | `created`| `TIMESTAMP`| | `modified`| `TIMESTAMP`| | `output`| `SUPER`| ## Warehouse Operations Use GraphQL queries and mutations to execute queries and describe results in the data warehouse: - [`Query.warehouse.describeStatement()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.describe-statement): Describe the status of executing query - [`Query.warehouse.describeTable()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.describe-table): Describe a table. - [`Query.warehouse.getStatementResult()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.get-statement-result): Retrieve the result of a table. - [`Query.warehouse.listDatabases()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.list-databases): List databases available to query. - [`Query.warehouse.listSchemas()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.list-schemas): List schemas available in database. - [`Query.warehouse.listStatements()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.list-statements): List recent executing statements. - [`Query.warehouse.listTables()`](https://www.twisp.com/docs/reference/graphql/queries.md#warehouse.list-tables): List tables in schema. - [`Mutation.warehouse.executeStatementSync()`](https://www.twisp.com/docs/reference/graphql/mutations.md#warehouse.execute-statement-sync): Execute a SQL statement and synchronously wait for result. - [`Mutation.warehouse.batchExecuteStatement()`](https://www.twisp.com/docs/reference/graphql/mutations.md#warehouse.batch-execute-statement): Execute a number of SQL statements asynchronously. - [`Mutation.warehouse.cancelStatement()`](https://www.twisp.com/docs/reference/graphql/mutations.md#warehouse.cancel-statement): Cancel a running statement. - [`Mutation.warehouse.executeStatement()`](https://www.twisp.com/docs/reference/graphql/mutations.md#warehouse.execute-statement): Execute a single SQL statement asynchronously. --- # ACH RDFI Reference for the ACH RDFI processor for a Twisp Ledger. ## The Basics The ACH RDFI processor enables management of ACH transactions within the Twisp ledger system from the perspective of a Receiving Depository Financial Institution (RDFI). It provides endpoints for receiving ACH files, handling transaction postings, processing returns, managing reversals, and integrating these activities into the financial ledger. The Automated Clearing House (ACH) network facilitates electronic financial transactions. An RDFI is responsible for receiving and processing incoming transactions, ensuring they are appropriately credited to beneficiary accounts while maintaining compliance with ACH rules and standards. This processor supports streamlined transaction management and regulatory adherence. ```mermaid graph TD A(Create file upload) --> B(Upload ACH file) B --> C(Process ACH file) C --> D{Decision ACH transaction
Webhook} D -->|Settle| E(Post to ledger account) D -->|Pending| P(Hold in pending layer) D -->|Return with reason| F(Generate ACH return) D -->|Retry| D P -->|executeTask Pending
new accountId| P P -->|executeTask Settle| E P -->|executeTask Return| F G(Update ACH transaction status) E --> G F --> G G --> H{More transactions in file?} H -->|Yes| D H -->|No| I(Update ACH file status) I --> J(Read ACH file status) ``` ## ACH RDFI Workflow ### 0. Prerequisite ACH RDFI Config An ACH config contains information for processing and generating ACH files. You will need to create an endpoint for responding to processing requests: ```graphql mutation CreateEndpoint { events { createEndpoint( input: { endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" status: ENABLED endpointType: ACH_PROCESSOR url: "https://webhook.site/ach-testing" subscription: [] description: "ACH webhook processor" } ) { endpointId } } } ``` Create the required accounts for processing ach transactions: ```graphql mutation CreateAccounts { # ACH Settlement account settlement: createAccount( input:{ accountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" code: "settlement.ach" name: "ach settlement" normalBalanceType: DEBIT config: { enableConcurrentPosting: true } } ) { accountId } # Suspense/Exception Account suspenseAndException: createAccount( input:{ accountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" code: "suspense.ach" name: "ach suspense" config: { enableConcurrentPosting: true } } ) { accountId } } ``` And then create a configuration that specifies the various accounts required for processing ACH files. **Request** ```graphql mutation CreateConfiguration { ach { createConfiguration( input: { configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" endpointId: "b84512f1-a67e-4dc2-94dd-66c48b4d13fb" settlementAccountId: "37f7e8a6-171f-411d-ad59-7b1f40f505ea" exceptionAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" suspenseAccountId: "3171b0c2-6e9f-41aa-a5a6-ee927deb27cf" feeAccountId: "62808a87-0b11-4dce-8877-767b70f029af" journalId: "00000000-0000-0000-0000-000000000000" odfiHeaderConfiguration: { immediateDestination: "026009593" immediateDestinationName: "ACME BANK" immediateOrigin: "231380104" immediateOriginName: "ZUZU" } timeZone: "America/Los_Angeles" } ) { configId } } } ``` **Response** ```json { "data": { "ach": { "createConfiguration": { "configId": "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" } } } } ``` #### Accounts 1. `settlementAccountId` is the account that represents entries as they transit the system to end user or exception/expense accounts. 2. `exceptionAccountId` is the account that's posted to when a transaction fails to post to a customer account due to velocity controls, account state or some unknown reason. 3. `suspenseAccountId` is the account that's posted to when the desired account does not exist. ### 1. Upload ACH file All RDFI ACH files received from the network must be uploaded. [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md) uploads a new ACH file containing transactions for processing. ```graphql mutation CreateAchUpload{ files { createUpload( input:{ key: "nacha_file.ach" uploadType: ACH contentType: "text/plain" } ) { uploadURL } } } ``` Example Upload of file with `curl`: ``` curl -T nacha_file.ach -XPUT '' ``` ### 2. Process ACH file After a file is uploaded, [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/graphql/mutations.md#ach.process-file) will begin processing the uploaded ACH file. **Request** ```graphql mutation ProcessFile { ach { processFile( input: { configId: "1dc71d60-f463-4bb6-b82a-ab42e2f923ff" fileKey: "ppd-credit.ach" fileType: RDFI } ) { fileId } } } ``` **Response** ```json { "data": { "ach": { "processFile": { "fileId": "b0d76a9a-afcd-4b1b-b115-01b88d7b84e6" } } } } ``` ### 3. Respond to ACH RDFI transaction webhooks Webhooks will be triggered for all entries in the processed ACH file. 1. From the ACH entry details determine the `journalId` and `accountId` the transaction should be posted to. 1. Run any customer defined transaction checks to determine if a return is warranted. 1. Return a response for how Twisp should proceed in processing the transaction along with the timestamp for settlement. > **Tip:** > > #### Interaction with velocity limits > > Any [velocity controls](https://www.twisp.com/docs/reference/ledger/velocity-controls.md) attached to the target account are enforced when the entry is posted — at the `ENCUMBRANCE` layer on **CREATE** and at the `SETTLED` layer on **SETTLE**. If a control is tripped at either state, Twisp automatically executes a return instead of posting the transaction. > > To override enforcement for specific entries, return `metadata` and `entryMetadata` on your webhook response and reference those values in the limit's [`condition`](https://www.twisp.com/docs/reference/ledger/velocity-controls.md#overriding-velocity-control-enforcement) so the entry is excluded from the limit. #### Sample webhooks ```json { "workflowName": "ACH.RDFI.DR", "workflowTask": "CREATE", "executionId": "60f7ac42-ff72-48c7-af58-ee1f9a2db1e0", "configurationId": "3a1b9c52-7d44-4f0e-9c1a-2b6e8f4d10aa", "fileId": "8e2c4f17-5b9a-4d3e-8f21-9a7c6b3d5e02", "fileKey": "incoming/ach/20251114/payroll.ach", "fileHeader": { "id": "", "immediateDestination": "", "immediateOrigin": "", "fileCreationDate": "", "fileCreationTime": "", "fileIDModifier": "", "immediateDestinationName": "", "immediateOriginName": "", "referenceCode": "" }, "batchHeader": { "id": "", "serviceClassCode": "", "companyName": "", "companyDiscretionaryData": "", "companyIdentification": "", "standardEntryClassCode": "", "companyEntryDescription": "", "companyDescriptiveDate": "", "effectiveEntryDate": "", "settlementDate": "", "originatorStatusCode": "", "odfiIdentification": "", "batchNumber": "" }, "entryDetail": { "id": "", "transactionCode": "", "rdfiIdentification": "", "checkDigit": "", "dfiAccountNumber": "", "amount": "", "identificationNumber": "", "individualName": "", "discretionaryData": "", "addendaRecordIndicator": "", "traceNumber": "", "addenda02": {}, "addenda05": {}, "addenda98": {}, "addenda98Refused": {}, "addenda99": {}, "addenda99Contested": {}, "addenda99Dishonored": {}, "category": "" } } ``` ```json { "action": "SETTLE | PENDING | RETURN | RETRY", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "when": "2024-01-01T23:20:50Z", "addenda99": { "returnCode": "R01", "dateOfDeath": "", "addendaInformation": "" }, "metadata": { "key": "value" } } ``` ##### Example Responses Where `now` is `2000-02-01T00:00:00.000Z` Settle Now: ```json { "action": "SETTLE", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "when": "2000-01-31T23:59:59.000Z", "metadata": { "key": "value" } } ``` Settle in two days: ```json { "action": "SETTLE", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "when": "2000-02-03T00:00:00.000Z", "metadata": { "key": "value" } } ``` Settle based on settlement date defined in batch: ```json { "action": "SETTLE", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "metadata": { "key": "value" } } ``` Accept but hold as pending (Twisp will not auto-settle; settle or return later via `workflow.executeTask` using the `executionId`): ```json { "action": "PENDING", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "metadata": { "review": "manual_fraud_check" } } ``` While the entry is held, you can move the hold to a different account by executing the `PENDING` task again with a new `accountId` param — Twisp relocates the held funds on the same layer, and a later settle or return acts on the new account. See [moving a pending hold](https://www.twisp.com/docs/reference/ach/rdfi.md#option-2-pending-accept-and-hold) for details. Retry Twisp will exponentially backoff: ```json { "action": "RETRY" } ``` Decline with insufficient funds return code: ```json { "action": "RETURN", "accountId": "d2f7183f-8e9c-45e7-9a98-ef1897ddb930", "addenda99": { "returnCode": "R01" }, "metadata": { "key": "value" } } ``` ##### Dishonored return webhooks and contests When `workflowTask` is `DISHONOR`, the request includes `addenda99Dishonored`. Return `{"action":"CONTEST"}` to contest immediately with Twisp's default reason-code mapping. Auto-pending configurations do not send this webhook, even when an endpoint is configured. A matched dishonor posts to the pending account's settled layer and remains at `DISHONOR`. Move it to another account with `Mutation.workflow.executeTask()` using `task: "DISHONOR"` and `params: {accountId: "..."}`. The move also accepts `effective`, `metadata`, and `entryMetadata`; its annotations apply only to the move. Then contest it with a separate `CONTEST` task if needed. The webhook response cannot set `addenda99Contested`. To choose a code, return an empty webhook response and then call `Mutation.workflow.executeTask()` with `task: "CONTEST"` and this parameter shape: ```graphql params: { addenda99Contested: { contestedReturnCode: "R71" } } ``` Valid codes are `R71` through `R77`. Unknown fields and invalid codes return an error. See [Dishonored Returns and Contests](https://www.twisp.com/docs/reference/ach/rdfi.md#dishonored-returns-and-contests) for the complete webhook and GraphQL examples, allowed fields, and default mappings. Do not put `contestedReturnCode` directly under `params`. It must be nested under `addenda99Contested`. #### Return codes | Code | Reason | Description | |----|-----|------| | `R01` | Insufficient Funds | Available balance is not sufficient to cover the dollar value of the debit entry | | `R02` | Account Closed | Previously active account has been closed by customer or RDFI | | `R03` | No Account/Unable to Locate Account | Account number structure is valid and passes editing process, but does not correspond to individual or is not an open account | | `R04` | Invalid Account Number | Account number structure not valid; entry may fail check digit validation or may contain an incorrect number of digits. | | `R05` | Improper Debit to Consumer Account | A CCD, CTX, or CBR debit entry was transmitted to a Consumer Account of the Receiver and was not authorized by the Receiver | | `R06` | Returned per ODFI's Request | ODFI has requested RDFI to return the ACH entry (optional to RDFI - ODFI indemnifies RDFI) | | `R07` | Authorization Revoked by Customer | Consumer, who previously authorized ACH payment, has revoked authorization from Originator (must be returned no later than 60 days from settlement date and customer must sign affidavit) | | `R08` | Payment Stopped | Receiver of a recurring debit transaction has stopped payment to a specific ACH debit. RDFI should verify the Receiver's intent when a request for stop payment is made to insure this is not intended to be a revocation of authorization | | `R09` | Uncollected Funds | Sufficient book or ledger balance exists to satisfy dollar value of the transaction, but the dollar value of transaction is in process of collection (i.e., uncollected checks) or cash reserve balance below dollar value of the debit entry. | | `R10` | Customer Advises Originator is Not Known to Receiver and/or Originator is Not Authorized by Receiver to Debit Receiver’s Account | The receiver does not know the Originator’s identity and/or has not authorized the Originator to debit. Alternatively, for ARC, BOC, and POP entries, the signature is not authentic or authorized. | | `R11` | Customer Advises Entry Not in Accordance with the Terms of the Authorization | The Originator and Receiver have a relationship, and an authorization to debit exists, but there is an error or defect in the payment such that the entry does not conform to the terms of the authorization. The Originator may correct the error and submit a new entry within 60 days of the return entry settlement date without the need for re-authorization by the Receiver. | | `R12` | Branch Sold to Another DFI | Financial institution receives entry destined for an account at a branch that has been sold to another financial institution. | | `R13` | RDFI not qualified to participate | Financial institution does not receive commercial ACH entries | | `R14` | Representative payee deceased or unable to continue in that capacity | The representative payee authorized to accept entries on behalf of a beneficiary is either deceased or unable to continue in that capacity | | `R15` | Beneficiary or bank account holder | (Other than representative payee) deceased* - (1) the beneficiary entitled to payments is deceased or (2) the bank account holder other than a representative payee is deceased | | `R16` | Bank account frozen | Funds in bank account are unavailable due to action by RDFI or legal order | | `R17` | File record edit criteria | Fields rejected by RDFI processing (identified in return addenda) | | `R18` | Improper effective entry date | Entries have been presented prior to the first available processing window for the effective date. | | `R19` | Amount field error | Improper formatting of the amount field | | `R20` | Non-payment bank account | Entry destined for non-payment bank account defined by reg. | | `R21` | Invalid company ID number | The company ID information not valid (normally CIE entries) | | `R22` | Invalid individual ID number | Individual id used by receiver is incorrect (CIE entries) | | `R23` | Credit entry refused by receiver | Receiver returned entry because minimum or exact amount not remitted, bank account is subject to litigation, or payment represents an overpayment, originator is not known to receiver or receiver has not authorized this credit entry to this bank account | | `R24` | Duplicate entry | RDFI has received a duplicate entry | | `R25` | Addenda error | Improper formatting of the addenda record information | | `R26` | Mandatory field error | Improper information in one of the mandatory fields | | `R27` | Trace number error | Original entry trace number is not valid for return entry; or addenda trace numbers do not correspond with entry detail record | | `R28` | Transit routing number check digit error | Check digit for the transit routing number is incorrect | | `R29` | Corporate customer advises not authorized | RDFI has been notified by corporate receiver that debit entry of originator is not authorized | | `R30` | RDFI not participant in check truncation program | Financial institution not participating in automated check safekeeping application | | `R31` | Permissible return entry (CCD and CTX only) | RDFI has been notified by the ODFI that it agrees to accept a CCD or CTX return entry | | `R32` | RDFI non-settlement | RDFI is not able to settle the entry | | `R33` | Return of XCK entry | RDFI determines at its sole discretion to return an XCK entry; an XCK return entry may be initiated by midnight of the sixtieth day following the settlement date if the XCK entry | | `R34` | Limited participation RDFI | RDFI participation has been limited by a federal or state supervisor | | `R35` | Return of improper debit entry | ACH debit not permitted for use with the CIE standard entry class code (except for reversals) | | `R37` | Source Document Presented for Payment (Adjustment Entry) | The source document to which an ARC, BOC or POP entry relates has been presented for payment. RDFI must obtain a Written Statement and return the entry within 60 days following Settlement Date | | `R38` | Stop Payment on Source Document (Adjustment Entry) | A stop payment has been placed on the source document to which the ARC or BOC entry relates. RDFI must return no later than 60 days following Settlement Date. No Written Statement is required as the original stop payment form covers the return | | `R39` | Improper Source Document | The RDFI has determined the source document used for the ARC, BOC or POP entry to its Receiver's account is improper. | #### Used for ENR entries and are initiated by a Federal Government Agency | Code | Reason | Description | |----|-----|------| | `R40` | Return of ENR Entry by Federal Government Agency (ENR Only) | This return reason code may only be used to return ENR entries and is at the federal Government Agency's Sole discretion | | `R41` | Invalid Transaction Code (ENR only) | Either the Transaction Code included in Field 3 of the Addenda Record does not conform to the ACH Record Format Specifications contained in Appendix Three (ACH Record Format Specifications) or it is not appropriate with regard to an Automated Enrollment Entry. | | `R42` | Routing Number/Check Digit Error (ENR Only) | The Routing Number and the Check Digit included in Field 3 of the Addenda Record is either not a valid number or it does not conform to the Modulus 10 formula. | | `R43` | Invalid DFI Account Number (ENR Only) | The Receiver's account number included in Field 3 of the Addenda Record must include at least one alphameric character. | | `R44` | Invalid Individual ID Number/Identification Number (ENR only) | The Individual ID Number/Identification Number provided in Field 3 of the Addenda Record does not match a corresponding ID number in the Federal Government Agency's records. | | `R45` | Invalid Individual Name/Company Name (ENR only) | The name of the consumer or company provided in Field 3 of the Addenda Record either does not match a corresponding name in the Federal Government Agency's records or fails to include at least one alphameric character. | | `R46` | Invalid Representative Payee Indicator (ENR Only) | The Representative Payee Indicator Code included in Field 3 of the Addenda Record has been omitted or it is not consistent with the Federal Government Agency's records. | | `R47` | Duplicate Enrollment (ENR Only) | The Entry is a duplicate of an Automated Enrollment Entry previously initiated by a DFI. | #### Used for RCK entries only and are initiated by an RDFI | Code | Reason | Description | |----|-----|------| | `R50` | State Law Affecting RCK Acceptance | RDFI is located in a state that has not adopted Revised Article 4 of the UCC or the RDFI is located in a state that requires all canceled checks to be returned within the periodic statement | | `R51` | Item Related to RCK Entry is Ineligible or RCK Entry is Improper | The item to which the RCK entry relates was not eligible, Originator did not provide notice of the RCK policy, signature on the item was not genuine, the item has been altered or amount of the entry was not accurately obtained from the item. RDFI must obtain a Written Statement and return the entry within 60 days following Settlement Date | | `R52` | Stop Payment on Item (Adjustment Entry) | A stop payment has been placed on the item to which the RCK entry relates. RDFI must return no later than 60 days following Settlement Date. No Written Statement is required as the original stop payment form covers the return. | | `R53` | Item and RCK Entry Presented for Payment (Adjustment Entry) | Both the RCK entry and check have been presented for payment. RDFI must obtain a Written Statement and return the entry within 60 days following Settlement Date | #### Used by the ODFI for dishonored return entries | Code | Reason | Description | |----|-----|------| | `R61` | Misrouted Return | The financial institution preparing the Return Entry (the RDFI of the original Entry) has placed the incorrect Routing Number in the Receiving DFI Identification field. | | `R62` | Return of Erroneous or Reversing Debit | The reversal process caused, or did not correct, an unintended credit to the receiver. | | `R67` | Duplicate Return | The ODFI has received more than one Return for the same Entry. | | `R68` | Untimely Return | The Return Entry has not been sent within the time frame established by these Rules. | | `R69` | Field Error(s) | One or more of the field requirements are incorrect. | | `R70` | Permissible Return Entry Not Accepted/Return Not Requested by ODFI | The ODFI has received a Return Entry identified by the RDFI as being returned with the permission of, or at the request of, the ODFI, but the ODFI has not agreed to accept the Entry or has not requested the return of the Entry. | #### Used by the RDFI for contested dishonored return entries | Code | Reason | Description | |----|-----|------| | `R71` | Misrouted Dishonored Return | The financial institution preparing the dishonored Return Entry (the ODFI of the original Entry) has placed the incorrect Routing Number in the Receiving DFI Identification field. | | `R72` | Untimely Dishonored Return | The dishonored Return Entry has not been sent within the designated time frame. | | `R73` | Timely Original Return | The RDFI is certifying that the original Return Entry was sent within the time frame designated in these Rules. | | `R74` | Corrected Return | The RDFI is correcting a previous Return Entry that was dishonored using Return Reason Code R69 (Field Error(s)) because it contained incomplete or incorrect information. | | `R75` | Return Not a Duplicate | The Return Entry was not a duplicate of an Entry previously returned by the RDFI. | | `R76` | No Errors Found | The original Return Entry did not contain the errors indicated by the ODFI in the dishonored Return Entry. | | `R77` | Non-Acceptance of R62 Dishonored Return | The RDFI does not accept an R62 dishonored Return. | #### Used by Gateways for the return of international payments | Code | Reason | Description | |----|-----|------| | `R80` | IAT Entry Coding Error | The IAT Entry is being returned due to one or more of the following conditions: Invalid DFI/Bank Branch Country Code, invalid DFI/Bank Identification Number Qualifier, invalid Foreign Exchange Indicator, invalid ISO Originating Currency Code, invalid ISO Destination Currency Code, invalid ISO Destination Country Code, invalid Transaction Type Code | | `R81` | Non-Participant in IAT Program | The IAT Entry is being returned because the Gateway does not have an agreement with either the ODFI or the Gateway's customer to transmit Outbound IAT Entries. | | `R82` | Invalid Foreign Receiving DFI Identification | The reference used to identify the Foreign Receiving DFI of an Outbound IAT Entry is invalid. | | `R83` | Foreign Receiving DFI Unable to Settle | The IAT Entry is being returned due to settlement problems in the foreign payment system. | | `R84` | Entry Not Processed by Gateway | For Outbound IAT Entries, the Entry has not been processed and is being returned at the Gateway's discretion because either (1) the processing of such Entry may expose the Gateway to excessive risk, or (2) the foreign payment system does not support the functions needed to process the transaction. | | `R85` | Incorrectly Coded Outbound International Payment | The RDFI/Gateway has identified the Entry as an Outbound international payment and is returning the Entry because it bears an SEC Code that lacks information required by the Gateway for OFAC compliance. | ### 4. Generate an ACH Return File When RDFI file transaction processing is complete, a return file can be generated. ```graphql mutation GenerateAchReturnFile{ ach { generateFile( input:{ configId: "b96d358e-50b8-4ae5-8b07-2e8f33f396c6" key: "nacha_file_return.ach" type: RDFI_RETURN } ) { key } } } ``` ### 5. Download ACH Return File ```graphql mutation DownloadAchReturn { files { createDownload(key: "nacha_file_return.ach") { downloadURL } } } ``` ## Journal Posting Lifecycle All ACH transactions are managed via workflows. Each individual ACH transaction is assigned a fixed `executionId` and state transitions on those tasks are ran by the ACH RDFI processor. Each state transition may post one or more transactions. > **Note:** > > Workflows allow you to easily observe all historical actions taken on a particular `executionId`. > > Learn more about workflows in ... ### Workflows The following workflows are utilized in the ACH RDFI processor. #### ACH RDFI Debit ```mermaid graph TD CREATE(CREATE
ACH_ENCUMBRANCE_DR
_) SETTLE(SETTLE
ACH_ENCUMBRANCE_REVERSAL_DR
ACH_SETTLE_DR
_) RETURN(RETURN
ACH_*_RETURN_CR
_) CREATE --> SETTLE CREATE --> RETURN SETTLE --> RETURN ``` #### ACH RDFI Credit ```mermaid graph TD CREATE(CREATE
ACH_ENCUMBRANCE_CR
_) SETTLE(SETTLE
ACH_ENCUMBRANCE_REVERSAL_CR
ACH_SETTLE_CR
_) RETURN(RETURN
ACH_*_RETURN_DR
_) CREATE --> SETTLE CREATE --> RETURN SETTLE --> RETURN ``` ### TranCodes ```json { "data": { "1": { "code": "SYS_ACH_ENCUMBRANCE_CANCEL_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_CANCEL_DR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_CANCEL_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "2": { "code": "SYS_ACH_ENCUMBRANCE_CANCEL_REVERSAL_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_CANCEL_CR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_CANCEL_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "3": { "code": "SYS_ACH_ENCUMBRANCE_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_CR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "4": { "code": "SYS_ACH_ENCUMBRANCE_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_DR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "5": { "code": "SYS_ACH_ENCUMBRANCE_RETURN_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_RETURN_DR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_RETURN_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "6": { "code": "SYS_ACH_ENCUMBRANCE_RETURN_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_RETURN_CR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_RETURN_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "7": { "code": "SYS_ACH_ENCUMBRANCE_REVERSAL_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_REVERSAL_DR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_REVERSAL_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "8": { "code": "SYS_ACH_ENCUMBRANCE_REVERSAL_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_ENCUMBRANCE_REVERSAL_CR'", "accountId": "uuid(params.accountId)", "layer": "ENCUMBRANCE", "direction": "CREDIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_ENCUMBRANCE_REVERSAL_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "ENCUMBRANCE", "direction": "DEBIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "9": { "code": "SYS_ACH_FEE_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_FEE_DR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.feeAmount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_FEE_CR'", "accountId": "uuid(params.feeAccountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.feeAmount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "10": { "code": "SYS_ACH_FEE_REIMBURSE_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_FEE_REIMBURSE_CR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.feeAmount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_FEE_REIMBURSE_DR'", "accountId": "uuid(params.feeAccountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.feeAmount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "11": { "code": "SYS_ACH_PENDING_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_PENDING_DR'", "accountId": "uuid(params.accountId)", "layer": "PENDING", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_PENDING_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "PENDING", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "12": { "code": "SYS_ACH_PENDING_CANCEL_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_PENDING_CANCEL_CR'", "accountId": "uuid(params.accountId)", "layer": "PENDING", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_PENDING_CANCEL_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "PENDING", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "13": { "code": "SYS_ACH_PENDING_CANCEL_REVERSAL_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_PENDING_CANCEL_REVERSAL_DR'", "accountId": "uuid(params.accountId)", "layer": "PENDING", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_PENDING_CANCEL_REVERSAL_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "PENDING", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "14": { "code": "SYS_ACH_PENDING_REVERSAL_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_PENDING_REVERSAL_DR'", "accountId": "uuid(params.accountId)", "layer": "PENDING", "direction": "DEBIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_PENDING_REVERSAL_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "PENDING", "direction": "CREDIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "15": { "code": "SYS_ACH_SETTLE_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_CR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_SETTLE_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "16": { "code": "SYS_ACH_SETTLE_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_DR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_SETTLE_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "17": { "code": "SYS_ACH_SETTLE_RETURN_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_RETURN_CR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_SETTLE_RETURN_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "18": { "code": "SYS_ACH_SETTLE_RETURN_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "STRING", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "STRING", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "Metadata to attach to transaction.", "default": "{}" }, { "name": "settleOn", "type": "TIMESTAMP", "description": "settleOn timestamp for ACH settlements.", "default": "1970-01-01T00:00:00Z" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_RETURN_DR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", }, { "entryType": "'ACH_SETTLE_RETURN_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "params.amount", "currency": "'USD'", "description": "''", "metadata": "{}", } ] }, "19": { "code": "SYS_ACH_SETTLE_REVERSAL_CR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "DECIMAL", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "DECIMAL", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "metadata for the transaction.", "default": "{}" }, { "name": "entryMetadata", "type": "JSON", "description": "metadata for the entry of accountId.", "default": "{}" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_REVERSAL_CR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "params.entryMetadata", }, { "entryType": "'ACH_SETTLE_REVERSAL_DR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "params.entryMetadata", } ] }, "20": { "code": "SYS_ACH_SETTLE_REVERSAL_DR", "params": [ { "name": "accountId", "type": "UUID", "description": "The account to place the hold on.", }, { "name": "settlementAccountId", "type": "UUID", "description": "The settlement account to use.", }, { "name": "feeAccountId", "type": "UUID", "description": "Optional fee account to use.", "default": "00000000-0000-0000-0000-000000000000" }, { "name": "feeAmount", "type": "DECIMAL", "description": "Optional decimal amount of the fee.", "default": "0" }, { "name": "journalId", "type": "UUID", "description": "The journal to post transactions to.", }, { "name": "amount", "type": "DECIMAL", "description": "The decimal amount.", }, { "name": "correlationId", "type": "STRING", "description": "Correlation identifier to group related transactions.", }, { "name": "effective", "type": "DATE", "description": "Effective date for the transaction.", }, { "name": "metadata", "type": "JSON", "description": "metadata for the transaction.", "default": "{}" }, { "name": "entryMetadata", "type": "JSON", "description": "metadata for the entry of accountId.", "default": "{}" } ], "transaction": { "effective": "params.effective", "journalId": "params.journalId", "correlationId": "params.correlationId", "externalId": "''", "description": "''", "metadata": "params.metadata" }, "entries": [ { "entryType": "'ACH_SETTLE_REVERSAL_DR'", "accountId": "uuid(params.accountId)", "layer": "SETTLED", "direction": "DEBIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "params.entryMetadata", }, { "entryType": "'ACH_SETTLE_REVERSAL_CR'", "accountId": "uuid(params.settlementAccountId)", "layer": "SETTLED", "direction": "CREDIT", "units": "decimal.Neg(params.amount)", "currency": "'USD'", "description": "''", "metadata": "params.entryMetadata", } ] } } } ``` ## Components of the ACH RDFI Processor ### Unmatched return lifecycle New unmatched regular, dishonored, and contested returns create an `ACH_RDFI_UNMATCHED_RETURN` execution using the inbound record ID. A regular return can execute `DISHONOR`; a dishonored return can execute `CONTEST`; a contested return remains in `CREATE`. Lifecycle tasks use the account selected by the current state when `accountId` is absent. Each current state can transition to itself. The self-transition accepts optional `accountId`, `effective`, `metadata`, and `entryMetadata`, corrects the live posting with a void and repost, and sends no additional ACH response. Omitted values are preserved and an unchanged request is a no-op. `DISHONOR` accepts a complete `addenda99Dishonored` object and defaults to R61 when it is absent. Outbound `CONTEST` accepts a complete `addenda99Contested` object and defaults to R71 with blank original-date fields. Twisp preserves valid caller-owned fields and assigns the outbound trace and physical line numbers. IAT and ADV dishonored or contested reply tasks are not supported. The CREATE account is the configured pending account when auto-pending is enabled and that account is present; otherwise it is the exception account. CREATE, DISHONOR, and CONTEST use advisory `WARN` velocity enforcement. Historical unknown postings remain executionless, and a later redrive does not reclassify a newly processed unknown record using a trace that arrived after its initial lookup. Direct calls to `SYS_ACH_UNKNOWN_RETURN_CR` and `SYS_ACH_UNKNOWN_RETURN_DR` use `accountId`; the former `exceptionAccountId` parameter is no longer accepted. The ACH RDFI Processor includes several core components: 1. **ACH File Management**: Supports upload and download of ACH files containing ACH transactions directed to the RDFI, initiating the process for distributing funds to beneficiary accounts. 2. **Transaction Posting**: Processes received transactions, crediting or debiting the relevant accounts as per the transaction instructions. 3. **Return Handling**: Manages any returns of transactions that cannot be completed, automatically generating return entries and files. 4. **ACH Reversals**: Processes ACH reversals submitted by an ODFI, ensuring that erroneous transactions are reversed in compliance with ACH standards and updating the ledgers accordingly. 5. **Status Monitoring**: Provides endpoints to track the status of received transactions, enabling RDFIs to maintain visibility into processing stages and outcomes. 6. **Error Reporting**: Offers detailed error reporting for transactions that encounter issues, allowing for efficient troubleshooting and resolution. 7. **Ledger Integration**: Ensures that all processed, returned, and reversed transactions are accurately reflected in the Twisp ledger, maintaining up-to-date financial records. ## API Operations The ACH RDFI API supports a suite of GraphQL operations for managing incoming ACH transactions: - **ACH Configuration Operations** - [`Query.ach.config()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Get configuration for ACH protocol processing. - [`Mutation.ach.createConfig()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Create an ACH protocol config. - [`Mutation.ach.updateConfig()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Update an ACH protocol config. - **ACH File Operations** - [`Query.ach.file()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Monitor the status of an processed ACH file, including transactions and return file generation. - [`Mutation.ach.generateFile()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Generate an ACH file. - [`Mutation.ach.processFile()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Process an uploaded ACH file. - [`Mutation.files.createDownload()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Download ACH files containing ACH transactions for submission to the network. - [`Mutation.files.createUpload()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Upload a new ACH file containing ACH transactions for processing. - **Transaction Operations** - [`Query.ach.transaction()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Get details and status of an ACH transaction. - [`Query.ach.transactions()`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Query ACH transactions. - [`Mutation.ach.updateTransaction`](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md): Update an ACH transaction. ## Further Reading For more information on ACH file structure and reception procedures, see the [ACH File Reception Guide](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md). To integrate this API into your existing systems, refer to the [RDFI API Integration Tutorial](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md). For more context on the ACH network and RDFI responsibilities, explore the [ACH Network Overview](https://www.twisp.com/docs/reference/protocols/ach/rdfi.md).