Skip to main content
This reference documents every command and flag in the DualEntry CLI (dualentry), grouped by what you’re trying to do. Each entry shows the command, what it does, its arguments and flags, and copyable examples. Every command exits with code 0 on success, 1 when it runs but fails (for example, an API error or a missing login), and 2 when the command line itself is wrong. To install the CLI and run a first command step by step, see the CLI quickstart. The entries below are current as of dualentry-cli v0.1.18. Run dualentry <command> --help to check the version you have installed.

Set up the CLI

These commands install, upgrade, and remove the CLI, connect it to your DualEntry organization, and check its configuration and connection. This section also covers the global flags every command accepts.

Install the CLI

Install the CLI on macOS or Linux with Homebrew, uv, or an install script. The uv method requires Python 3.11 or later. The install script downloads a standalone dualentry binary into /usr/local/bin (set INSTALL_DIR to choose another directory), so it doesn’t need Python; it supports macOS and Linux on x86-64, and macOS on Apple silicon.
Install with Homebrew
Install with uv
Install with the install script
Once the CLI is installed, log in to connect it to your DualEntry organization.

Upgrade the CLI

Upgrade the CLI with the same method you installed it with. The CLI checks for a newer release once a day and, while one is available, prints a notice with the upgrade command each time it runs.
Upgrade with Homebrew
Upgrade with uv
Upgrade with the install script

Uninstall the CLI

Uninstall the CLI with the same method you installed it with. Before uninstalling, run dualentry auth logout to remove your stored credentials. To remove the CLI’s configuration as well, delete the ~/.dualentry directory.
Uninstall with Homebrew
Uninstall with uv
Uninstall an install-script copy

Log in

Opens your browser to sign in to DualEntry, then stores the resulting API key in your operating system’s keychain under the service name dualentry-cli and prints the signed-in email and organization ID. On a machine with no usable keychain, the key is stored in ~/.dualentry/tokens.json instead, so treat that file as a credential on shared hosts.For CI/CD and other headless environments, skip auth login and set the X_API_KEY environment variable to an API key. When it’s set, it takes precedence over a stored login.Flags:
  • --api-url (string, optional): API base URL to use instead of the default.
Log in through your browser
Authenticate with an API key instead, for CI/CD

Check your sign-in status

Prints the API URL, your email, and your organization ID, or says that you’re authenticated through X_API_KEY. Exits with code 1 and prints Not logged in. Run: dualentry auth login when there’s no credential.
Check which organization you're signed in to

Log out

Removes the stored API key from your keychain.
Log out

View your configuration

Prints the API URL, the output format setting, and the signed-in user and organization. The CLI keeps these settings in ~/.dualentry/config.toml.
Show the current configuration

Use a different API host

Saves a custom API base URL to your config file. Every organization, sandbox or production, uses https://api.dualentry.com, and the API key you sign in with decides which one you work against. Change the URL only to point the CLI at a different host entirely. The DUALENTRY_API_URL environment variable, when set, overrides the saved URL.Arguments:
  • URL (string, required): Custom API base URL.
Save a custom API host
Override the host for one session

Check that the API is reachable

Prints the API URL, the API’s status, and its server time. Exits with code 1 if the API can’t be reached.
Check API connectivity

Use global flags

Global flags go before the command name and apply to the whole invocation.With --retry, the CLI retries a request that fails with status 429, 502, 503, or 504, a 409 that carries a Retry-After header, or a network error or timeout. It waits one, two, and then four seconds between attempts, or the number of seconds in the response’s Retry-After header, capped at 60. Every request that creates or changes data carries an Idempotency-Key header, so a retried write isn’t applied twice.Flags:
  • --version, -v (boolean, optional): Print the CLI version and exit.
  • --retry (boolean, optional): Retry failed requests with exponential backoff, as described above.
  • --install-completion (boolean, optional): Install tab completion for your current shell.
  • --show-completion (boolean, optional): Print the completion script for your current shell, to copy it or customize the installation.
  • --help (boolean, optional): Show help for the CLI, or for any command or subcommand when placed after it.
Retry rate-limited requests during a large export
Install tab completion for your shell
Print the installed version

Work with records

Most commands are resource commands: one per record type, such as invoices, bills, or customers. Every resource command has the same subcommands, so the entries below cover all of them, with <resource> standing in for the command name. The table at the end of this section shows which subcommands and list filters each resource supports.Most transaction records, such as invoices, bills, and journal entries, have a record number, shown in the # column of list output, and an internal ID, shown in the ID column with a type prefix such as IN-12. Master data, such as customers and vendors, has only an ID.

List records

Returns one page of records as a table, or every page with --all. The filters each resource accepts vary; passing one it doesn’t support is a usage error that names the ones it does. --status takes draft, posted, or archived on transaction records.--all fetches pages of 100 records until it reaches the end, ignoring --limit but starting from --offset. It stops after 1,000 pages (100,000 records) and prints a command that resumes where it stopped. With --format json, the output is an object of the form {"items": [...], "count": N}, where count is the total number of matching records, not the number returned.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --search, -s (string, optional): Text to search for.
  • --status (string, optional): Return only records with this status: draft, posted, or archived.
  • --start-date (string, optional): Start of the date range to return, in YYYY-MM-DD format.
  • --end-date (string, optional): End of the date range to return, in YYYY-MM-DD format.
  • --company, -c (string, optional): Return only records for this company ID.
  • --customer (string, optional): Return only records for this customer ID.
  • --vendor (string, optional): Return only records for this vendor ID.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List posted invoices for September
List one vendor's bills
Search customers by name
Export every journal entry as JSON

Retrieve a record

Prints one record as a detail view, or as JSON with --format json. On resources with record numbers, get looks the value up as a record number first and, if no record has that number, as an internal ID. get-number and get-id look it up only one way, which is safer in scripts. These subcommands accept a display prefix, so IN-5821 and 5821 work the same. On resources without record numbers, get takes the ID.Arguments:
  • VALUE (string, required): Record number (the # column) or ID, for example IN-5821.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Arguments:
  • NUMBER (string, required): Record number, shown in the # column.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Arguments:
  • RECORD_ID (string, required): Record ID (for example IN-5821 or 5821).
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Retrieve an invoice by record number
Retrieve a journal entry by its ID
Retrieve a customer as JSON

Create a record

Creates a record from a JSON file and prints it. The file’s shape is the request body of the matching endpoint in the API reference; no subcommand accepts record fields as flags.Flags:
  • --file, -f (path, required): JSON file with record data.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Create an invoice from a file
Create a customer and print it as JSON

Update a record

Replaces a record with the contents of a JSON file, which the CLI sends as the body of a PUT request. Pass the record number on resources that have one, including recurring records, and the ID otherwise. Unlike get, update doesn’t strip a display prefix, so pass the bare value.Arguments:
  • RECORD_ID (string, required): Record ID.
Flags:
  • --file, -f (path, required): JSON file with update data.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Update an invoice

Delete a record

Deletes a record without asking for confirmation. Only custom fields, product tax codes, and recurring records can be deleted; on recurring records, pass the record number, and deleting one removes its schedule.Arguments:
  • RECORD_ID (string, required): Record ID.
Delete a recurring invoice schedule
Delete a custom field

Commands for each record type

The tables below list every resource command, grouped by area, with the subcommands it supports and the filters its list subcommand accepts.ReceivablesPayablesAccountingMaster dataRecurring records, contracts, budgets, and workflows

Intercompany journal entries

Intercompany journal entries have three extra subcommands for drafting an entry from a file, checking it, and posting it. Use the record subcommands to list, retrieve, create, and update them.

Generate an entry template

Prints a sample intercompany journal entry as JSON, or writes it to a file. On this subcommand, -o is short for --output.Flags:
  • --output, -o (path, optional): File to write the template to, instead of standard output.
Write a template to a file

Validate an entry

Checks a JSON file in order and stops at the first failure: the items array isn’t empty, every debit and credit is a valid amount, total debits equal total credits, and the lines span at least two companies. --online also confirms you can access every company_id in the file. Prints ✓ Valid, or the problem and exits with code 1.Flags:
  • --file, -f (path, required): JSON file to validate.
  • --online (boolean, optional): Also run checks that require API access.
Validate a file offline
Validate a file and check company access

Post a draft entry

Posts a draft intercompany journal entry. If the entry isn’t a draft, prints its current status and exits with code 1 without changing it.Arguments:
  • NUMBER (string, required): Record number of the draft to post.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Create an entry as a draft, then post it

Accounts and statistical journals

The accounts commands look up accounts in your chart of accounts, and the statistical-journals commands list, create, update, and attach files to statistical journal entries.

List accounts

Lists the accounts in your chart of accounts.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --search, -s (string, optional): Text to search for.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Search accounts

Retrieve an account

Prints one account, looked up by account number.Arguments:
  • ACCOUNT_ID (integer, required): Account number.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Retrieve an account by number

List statistical journals

Lists statistical journals. Date filters take YYYY-MM-DD values, --updated-after and --updated-before take ISO 8601 timestamps, and the number and account filters take comma-separated lists.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --search, -s (string, optional): Text to search for.
  • --status (string, optional): Return only records with this status: draft, posted, or archived.
  • --company, -c (string, optional): Return only records for this company ID.
  • --date-start (string, optional): Start of the journal date range to return, in YYYY-MM-DD format.
  • --date-end (string, optional): End of the journal date range to return, in YYYY-MM-DD format.
  • --period-start (string, optional): Earliest period start date to return, in YYYY-MM-DD format.
  • --period-end (string, optional): Latest period end date to return, in YYYY-MM-DD format.
  • --number (comma-separated integers, optional): Return only journals with these record numbers.
  • --account-id (comma-separated integers, optional): Return only journals for these account IDs.
  • --account-number (string, optional): Return only journals for these account numbers, separated by commas.
  • --line-account-id (comma-separated integers, optional): Return only journals with lines on these account IDs.
  • --line-account-number (string, optional): Return only journals with lines on these account numbers, separated by commas.
  • --updated-after (string, optional): Return only journals updated after this time, as an ISO 8601 timestamp.
  • --updated-before (string, optional): Return only journals updated before this time, as an ISO 8601 timestamp.
  • --ordering (string, optional): API field to sort by. Prefix it with - to sort in descending order.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List journals for September
List journals that touch two accounts

Retrieve, create, or update a statistical journal

Work with a single statistical journal. get accepts the record number with or without its SJ- prefix, and create and update read the journal from a JSON file.Get a statistical journal by number.Arguments:
  • VALUE (string, required): Record number (the # column) or prefixed number, for example SJ-3.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Create a statistical journal from a JSON file.Flags:
  • --file, -f (path, required): JSON file with record data.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Update a statistical journal.Arguments:
  • NUMBER (string, required): Record number of the journal to update.
Flags:
  • --file, -f (path, required): JSON file with update data.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Retrieve a statistical journal
Create a statistical journal
Update a statistical journal

Attach files to a statistical journal

Uploads one or more files to a statistical journal. Pass --file once per file.Arguments:
  • NUMBER (string, required): Record number of the journal.
Flags:
  • --file, -f (path, required, repeatable): File to attach. Repeat the flag to attach more than one file.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Attach two files

Bank matching

The bank-match commands reconcile bank-feed transactions against DualEntry transactions.

Check matching progress

Shows how many bank-feed rows sit in each pipeline stage. Matching is still running while unprocessed, awaiting_ai, or ai_in_progress is above zero.Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Check matching progress

List bank-feed transactions

Lists bank-feed transactions, or prints one by ID. Expired rows are hidden unless you pass --include-expired.List bank-feed transactions.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --financial-account-id (integer, optional): Return only transactions for this connected bank or credit-card account ID.
  • --matching-status (string, optional): Matching stage to filter by, such as unprocessed, ai_suggested, matched, no_match, or excluded.
  • --date-from (datetime, optional): Earliest transaction date to return, in YYYY-MM-DD format.
  • --date-to (datetime, optional): Latest transaction date to return, in YYYY-MM-DD format.
  • --is-posted, --not-posted (boolean, optional): --is-posted returns only posted transactions and --not-posted only pending ones. Omit both to return all transactions.
  • --include-expired (boolean, optional): Include expired bank-feed rows, which are hidden by default.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Get one bank-feed transaction by ID.Arguments:
  • FINANCIAL_TRANSACTION_ID (integer, required): Bank-feed transaction ID from bank-match bank-transactions list.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List unprocessed rows since September 1
Show one bank-feed transaction

Review suggested matches

Lists the matches DualEntry suggests for bank-feed rows, or prints one suggestion by ID.List bank-match suggestions.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --financial-transaction-id (integer, optional): Return only suggestions for this bank-feed row ID.
  • --suggestion-type (string, optional): Kind of suggestion: match to pair with an existing transaction, or create to draft a new one.
  • --highest-ranked (boolean, optional): Return only the top-ranked suggestion for each bank-feed row, which is what the DualEntry app shows by default.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Get one bank-match suggestion by ID.Arguments:
  • SUGGESTION_ID (integer, required): Suggestion ID from bank-match suggestions list.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Show the top suggestion for one bank-feed row

Confirm a match

Confirms a match between a bank-feed row and DualEntry transactions. Pass --financial-transaction-id with exactly one of --transaction-id or --entry-id for a one-to-one or partial match, or a file for one-to-one and many-to-many matches. A file can’t be combined with the ID flags.Flags:
  • --file, -f (path, optional): JSON file with the full match request, for one-to-one or many-to-many matches. Can’t be combined with the ID flags.
  • --financial-transaction-id (integer, optional): Bank-feed row ID to match one-to-one. Required when you don’t pass --file.
  • --transaction-id (integer, optional): DualEntry transaction ID to pair with in a one-to-one match. Pass this or --entry-id, not both.
  • --entry-id (integer, optional): DualEntry entry ID for a partial match. Pass this or --transaction-id, not both.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Match one bank-feed row to one transaction
Confirm a many-to-many match from a file

Undo a match

Undoes a confirmed match. Pass exactly one of the two flags; unmatching any member dissolves the whole match group.Flags:
  • --financial-transaction-id (integer, optional): Bank-feed row ID in the match group to undo. Pass this or --match-group-id.
  • --match-group-id (integer, optional): Match group ID from a prior match response. Pass this or --financial-transaction-id.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Undo a match group

Generate a match file

Prints a sample match file for bank-match match --file, or writes it to a file. On this subcommand, -o is short for --output.Flags:
  • --output, -o (path, optional): File to write the template to, instead of standard output.
  • --type, -t (string, default 1:1): Template type: 1:1, m:n, or partial.
Write a many-to-many match template

Bank connections

The bank-connections commands register bank connections, their accounts, and their transactions through the API, for organizations that send bank data to DualEntry themselves.

List bank connections

Lists your bank connections, or prints one by ID.List bank connections.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --updated-after (datetime, optional): Return only connections updated at or after this time, as an ISO 8601 timestamp.
  • --updated-before (datetime, optional): Return only connections updated at or before this time, as an ISO 8601 timestamp.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Get one bank connection by ID.Arguments:
  • CONNECTION_ID (integer, required): DualEntry bank connection ID.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List connections changed since September 1
Show one connection

Register a bank connection

Registers a bank connection, and optionally its accounts, from a JSON file.Flags:
  • --file, -f (path, required): JSON file with the connection to register.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Register a connection from a file

Unregister a bank connection

Unregisters a bank connection.Arguments:
  • CONNECTION_ID (integer, required): DualEntry bank connection ID to unregister.
Unregister a connection

Register accounts on a connection

Lists the accounts registered under a connection, or registers more from a JSON file.List accounts registered under a bank connection.Arguments:
  • CONNECTION_ID (integer, required): DualEntry bank connection ID.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Register accounts under an existing bank connection.Arguments:
  • CONNECTION_ID (integer, required): DualEntry bank connection ID.
Flags:
  • --file, -f (path, required): JSON file with the array of accounts to create.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List a connection's accounts
Register accounts from a file

Push bank transactions

Pushes a batch of bank transactions for a registered account from a JSON file.Arguments:
  • FINANCIAL_ACCOUNT_ID (integer, required): DualEntry financial account ID.
Flags:
  • --file, -f (path, required): JSON file with the batch of transactions to push.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Push a batch of transactions

Generate a bank connection file

Prints a sample JSON file for create, accounts create, or transactions push, or writes it to a file. On this subcommand, -o is short for --output.Flags:
  • --output, -o (path, optional): File to write the template to, instead of standard output.
  • --type, -t (string, default connection): Template type: connection, accounts, or transactions.
Write a transactions template

Data exports

The export-jobs commands request and track an on-demand refresh of a connected data warehouse destination, outside its regular schedule.

Request a data export

Requests an export. If one is already running, returns that job instead of starting another.Flags:
  • --integration-id (integer, optional): Destination integration ID. You can omit it when your organization has exactly one connected destination.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Request an export

Wait for a data export to finish

Checks a job until it finishes. Exits with code 0 when it completes, or 1 when it fails or the timeout passes, so it works as a step in a CI job.Arguments:
  • JOB_ID (integer, required): Export job ID to poll until finished.
Flags:
  • --interval (number, default 5.0, minimum 0.5): Seconds between status polls.
  • --timeout (number, default 1800.0, minimum 1.0): Give up after this many seconds (default 30 minutes).
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Request an export and wait for it

List and check data exports

Lists export jobs, most recent first, or prints one job.List destination data export jobs, most recent first.Flags:
  • --limit, -l (integer, default 20): Maximum number of records to return.
  • --offset (integer, default 0): Number of records to skip before the first one returned.
  • --all, -a (boolean, optional): Fetch every page of results instead of one.
  • --status (string, optional, repeatable): Return only jobs with this status: pending, running, completed, or failed. Repeat the flag to match more than one status.
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
Get one export job by ID. Poll this after create.Arguments:
  • JOB_ID (integer, required): Export job ID from export-jobs create or export-jobs list.
Flags:
  • --format, -o (string, default human): Output format: human (a table or detail view) or json.
List running and pending exports
Check one export
Last modified on October 9, 2026