Whisper Money

Search the documentation

Search pages and sections.

Accounts

An account is a bookkeeping record of money held somewhere: a manual one you keep up to date yourself, or a bank-connected one the bank sync keeps up to date. Nothing here moves money; that happens at the bank.

The example requests read your personal token from $WHISPER_MONEY_TOKEN: run export WHISPER_MONEY_TOKEN=wm_api_your_token_here before pasting them.

List accounts

GET /api/v1/accounts

Your accounts in a space, newest first, archived ones included. As in the app, another member's accounts are not listed.

Scope: read. A personal token needs api:read; an OAuth token needs api:use.

Parameters

Name In Type Required Description
limit query integer No How many objects to return, between 1 and 100. Defaults to 25.
starting_after query string (uuid) No An object id: return the page that follows it. Pass the last id of the page you have.
ending_before query string (uuid) No An object id: return the page that precedes it. Pass the first id of the page you have. Cannot be combined with starting_after.
space query string (uuid) No The id of the space to work in (see GET /spaces). Defaults to your personal space. On writes it may also be sent in the JSON body.

Response

200

Field Type Description
data array of Account
data[].id string (uuid) The account's id.
data[].space_id string (uuid) or null The id of the space the account is in.
data[].name string The account's name.
data[].type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" The account type. checking, credit_card, savings and others keep a transaction ledger; investment, retirement, loan and real_estate track a balance only.
data[].currency string The ISO 4217 currency the account is held in, which its amounts are in.
data[].bank object or null The bank the account is held at, if one is set: its id and name.
data[].bank.id string
data[].bank.name string
data[].is_connected boolean Whether the account is connected to a bank. A connected account's balances, currency and bank come from the sync: only its name, type and ownership can be changed, and it takes no manual balance.
data[].ownership_percentage integer The owner's share of the account, 1 to 100. Below 100 only that slice counts in their figures.
data[].ownership_applies_to_balance boolean Whether the ownership share applies to the balance too, not only to transactions.
data[].credit_card_detail object or null credit_card only, otherwise null: the card's limit and statement dates, in minor units and ISO dates. Later cycles repeat from the dates at statement_frequency. null while none is set.
data[].credit_card_detail.statement_closing_date string or null
data[].credit_card_detail.payment_due_date string or null
data[].credit_card_detail.statement_frequency "monthly" | "weekly"
data[].credit_card_detail.credit_limit integer or null
data[].credit_card_statement object or null credit_card only, otherwise null: an estimate of the card's next charge, computed from its statement dates and its transactions. It is not a transaction, and next_payment.is_final is false while the cycle is still open. null while the card has no statement dates.
data[].credit_card_statement.next_payment object
data[].credit_card_statement.next_payment.period_from string
data[].credit_card_statement.next_payment.closing_date string
data[].credit_card_statement.next_payment.due_date string
data[].credit_card_statement.next_payment.amount integer
data[].credit_card_statement.next_payment.is_final boolean
data[].credit_card_statement.next_payment.paid integer
data[].credit_card_statement.current_cycle object
data[].credit_card_statement.current_cycle.period_from string
data[].credit_card_statement.current_cycle.closing_date string
data[].credit_card_statement.current_cycle.due_date string
data[].credit_card_statement.current_cycle.amount integer
data[].credit_card_statement.payments array of object
data[].credit_card_statement.payments[].transaction_id string
data[].credit_card_statement.payments[].date string
data[].credit_card_statement.payments[].amount integer
data[].credit_card_statement.payments[].period_from string
data[].credit_card_statement.payments[].closing_date string
data[].credit_card_statement.payments[].due_date string
data[].credit_card_statement.previous_statement object
data[].credit_card_statement.previous_statement.period_from string
data[].credit_card_statement.previous_statement.closing_date string
data[].credit_card_statement.previous_statement.due_date string
data[].credit_card_statement.previous_statement.purchases integer
data[].credit_card_statement.previous_statement.paid integer
data[].credit_card_statement.previous_statement.pending integer
data[].credit_card_statement.previous_statement.has_recorded_purchases boolean
data[].credit_card_usage object or null credit_card only, otherwise null: how much of the card is in use. used is what is still to be charged between period_from and today, less the payments made on those statements, never below 0. available is limit minus it, negative over the limit; both limit and available are null while no credit limit is set.
data[].credit_card_usage.limit integer or null
data[].credit_card_usage.used integer
data[].credit_card_usage.available integer or null
data[].credit_card_usage.period_from string
data[].credit_card_usage.period_to string
data[].archived_at string (date-time) or null When the account was archived in the app, or null. An archived account keeps its history and still answers here.
data[].created_at string (date-time) or null When the account was created.
has_more boolean Whether more objects exist past this page, in the direction being walked.

Example request

curl https://whisper.money/api/v1/accounts \
  -H "Authorization: Bearer $WHISPER_MONEY_TOKEN"

Example response

{
    "data": [
        {
            "id": "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01",
            "space_id": "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60",
            "name": "Main checking",
            "type": "checking",
            "currency": "EUR",
            "bank": {
                "id": "0199a3f1-5b2c-7e8d-9f0a-1b2c3d4e5f60",
                "name": "BBVA"
            },
            "is_connected": false,
            "ownership_percentage": 100,
            "ownership_applies_to_balance": true,
            "credit_card_detail": null,
            "credit_card_statement": null,
            "credit_card_usage": null,
            "archived_at": null,
            "created_at": "2026-01-15T09:30:00+00:00"
        }
    ],
    "has_more": true
}

Errors

Status When
400 A malformed request: an unknown pagination cursor (invalid_cursor) or an invalid Idempotency-Key (invalid_idempotency_key).
401 No bearer token, or one that is unknown, expired or revoked.
403 The token lacks the scope (insufficient_scope), the account has no Pro plan (plan_required, with a subscribe_url) or it is a shared demo account (shared_account).
422 The request failed validation.
429 The rate limit is exhausted. Wait the seconds in Retry-After.

Create an account

POST /api/v1/accounts

Opens a manual account of any type, optionally with today's balance. A loan or a property takes its own details, and given a balance too it gets the monthly balance history in between generated, the older part in the background. A bank-connected account cannot be created here: it is only born when you connect your bank in the Whisper Money app, so banking_connection_id, external_account_id and is_connected are refused.

Scope: write. A personal token needs api:write (a read & write token); an OAuth token needs api:use.

Parameters

Name In Type Required Description
space query string (uuid) No The id of the space to work in (see GET /spaces). Defaults to your personal space. On writes it may also be sent in the JSON body.
Idempotency-Key header string No Any unique string up to 255 characters. Retrying with the same key within 24 hours returns the first response instead of repeating the request.

Request body

Field Type Required Description
name string Yes The account's name.
type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" Yes The account type. checking, credit_card, savings and others keep a transaction ledger; investment, retirement, loan and real_estate track a balance only.
currency_code "USD" | "EUR" | "GBP" | "JPY" | "CHF" | "CZK" | "CAD" | "AUD" | "NZD" | "CNY" | "INR" | "PKR" | "MXN" | "ARS" | "BOB" | "CLP" | "PYG" | "PEN" | "UYU" | "VES" | "BRL" | "COP" | "DOP" | "SAR" | "KWD" | "BTC" | "RSD" | "NGN" | "GHS" | "SEK" | "GTQ" | "HNL" | "HKD" | "THB" | "DKK" | "SGD" Yes The ISO 4217 currency the account is held in. Your first account also sets the currency your whole account is reported in, so it must be one of the primary currencies.
bank_id string or null No The id of the bank the account is held at, for its name and logo. It does not connect anything.
balance integer or null No The balance today, in minor units. On a loan or a property it is also where the generated balance history ends. Refused on a credit card, which takes a credit_limit instead.
linked_real_estate_account_id string (uuid) or null No loan only: id of the real_estate account this loan is the mortgage of. The property must have its details set and not be linked to another loan yet.
property_type "residential" | "commercial" | "land" | "vacation" | "other" No real_estate only: what kind of property it is. Required when the property's details are first created.
address string or null No real_estate only: the property's address.
purchase_price integer or null No real_estate only: what it was bought for, in minor units. With purchase_date and a balance, the value history in between is filled in.
purchase_date string (date) or null No real_estate only: when it was bought. Not in the future, not before 1900.
area_value number or null No real_estate only: floor area, in area_unit.
area_unit "sqm" | "sqft" | "acres" | "hectares" | null No real_estate only: the unit of area_value.
revaluation_percentage number or null No real_estate only: expected yearly revaluation, as a percentage.
notes string or null No real_estate only: free-text notes on the property.
linked_loan_account_id string (uuid) or null No real_estate only: id of one of your loan accounts that is this property's mortgage.
annual_interest_rate number or null No loan only: yearly interest rate, as a percentage.
loan_term_months integer or null No loan only: the term, in months.
original_amount integer or null No loan only: the amount originally borrowed, in minor units. A loan's details are created once annual_interest_rate, loan_term_months and original_amount are all known.
loan_start_date string (date) or null No loan only: when the loan started. Defaults to today.
statement_closing_date string (date) or null No credit_card only: a statement closing date. Later cycles repeat from it at statement_frequency. Send it with payment_due_date; both null clears them.
payment_due_date string (date) or null No credit_card only: when that statement is charged. On or after the closing date, at most 45 days later on a monthly card and 7 on a weekly one.
statement_frequency "monthly" | "weekly" | null No credit_card only: how often a statement closes. Left out, the stored one stays (monthly on a new card).
credit_limit integer or null No credit_card only: the card's credit limit, in minor units. null clears it.

Response

201

Field Type Description
data Account
data.id string (uuid) The account's id.
data.space_id string (uuid) or null The id of the space the account is in.
data.name string The account's name.
data.type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" The account type. checking, credit_card, savings and others keep a transaction ledger; investment, retirement, loan and real_estate track a balance only.
data.currency string The ISO 4217 currency the account is held in, which its amounts are in.
data.bank object or null The bank the account is held at, if one is set: its id and name.
data.bank.id string
data.bank.name string
data.is_connected boolean Whether the account is connected to a bank. A connected account's balances, currency and bank come from the sync: only its name, type and ownership can be changed, and it takes no manual balance.
data.ownership_percentage integer The owner's share of the account, 1 to 100. Below 100 only that slice counts in their figures.
data.ownership_applies_to_balance boolean Whether the ownership share applies to the balance too, not only to transactions.
data.credit_card_detail object or null credit_card only, otherwise null: the card's limit and statement dates, in minor units and ISO dates. Later cycles repeat from the dates at statement_frequency. null while none is set.
data.credit_card_detail.statement_closing_date string or null
data.credit_card_detail.payment_due_date string or null
data.credit_card_detail.statement_frequency "monthly" | "weekly"
data.credit_card_detail.credit_limit integer or null
data.credit_card_statement object or null credit_card only, otherwise null: an estimate of the card's next charge, computed from its statement dates and its transactions. It is not a transaction, and next_payment.is_final is false while the cycle is still open. null while the card has no statement dates.
data.credit_card_statement.next_payment object
data.credit_card_statement.next_payment.period_from string
data.credit_card_statement.next_payment.closing_date string
data.credit_card_statement.next_payment.due_date string
data.credit_card_statement.next_payment.amount integer
data.credit_card_statement.next_payment.is_final boolean
data.credit_card_statement.next_payment.paid integer
data.credit_card_statement.current_cycle object
data.credit_card_statement.current_cycle.period_from string
data.credit_card_statement.current_cycle.closing_date string
data.credit_card_statement.current_cycle.due_date string
data.credit_card_statement.current_cycle.amount integer
data.credit_card_statement.payments array of object
data.credit_card_statement.payments[].transaction_id string
data.credit_card_statement.payments[].date string
data.credit_card_statement.payments[].amount integer
data.credit_card_statement.payments[].period_from string
data.credit_card_statement.payments[].closing_date string
data.credit_card_statement.payments[].due_date string
data.credit_card_statement.previous_statement object
data.credit_card_statement.previous_statement.period_from string
data.credit_card_statement.previous_statement.closing_date string
data.credit_card_statement.previous_statement.due_date string
data.credit_card_statement.previous_statement.purchases integer
data.credit_card_statement.previous_statement.paid integer
data.credit_card_statement.previous_statement.pending integer
data.credit_card_statement.previous_statement.has_recorded_purchases boolean
data.credit_card_usage object or null credit_card only, otherwise null: how much of the card is in use. used is what is still to be charged between period_from and today, less the payments made on those statements, never below 0. available is limit minus it, negative over the limit; both limit and available are null while no credit limit is set.
data.credit_card_usage.limit integer or null
data.credit_card_usage.used integer
data.credit_card_usage.available integer or null
data.credit_card_usage.period_from string
data.credit_card_usage.period_to string
data.archived_at string (date-time) or null When the account was archived in the app, or null. An archived account keeps its history and still answers here.
data.created_at string (date-time) or null When the account was created.

Example request

curl -X POST https://whisper.money/api/v1/accounts \
  -H "Authorization: Bearer $WHISPER_MONEY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Main checking",
    "type": "checking",
    "currency_code": "EUR",
    "balance": 125000
}'

Example response

{
    "data": {
        "id": "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01",
        "space_id": "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60",
        "name": "Main checking",
        "type": "checking",
        "currency": "EUR",
        "bank": {
            "id": "0199a3f1-5b2c-7e8d-9f0a-1b2c3d4e5f60",
            "name": "BBVA"
        },
        "is_connected": false,
        "ownership_percentage": 100,
        "ownership_applies_to_balance": true,
        "credit_card_detail": null,
        "credit_card_statement": null,
        "credit_card_usage": null,
        "archived_at": null,
        "created_at": "2026-01-15T09:30:00+00:00"
    }
}

Errors

Status When
400 A malformed request: an unknown pagination cursor (invalid_cursor) or an invalid Idempotency-Key (invalid_idempotency_key).
401 No bearer token, or one that is unknown, expired or revoked.
403 The token lacks the scope (insufficient_scope), the account has no Pro plan (plan_required, with a subscribe_url) or it is a shared demo account (shared_account).
409 A request with the same Idempotency-Key is still being processed.
422 The request failed validation.
429 The rate limit is exhausted. Wait the seconds in Retry-After.

Retrieve an account

GET /api/v1/accounts/{account}

Scope: read. A personal token needs api:read; an OAuth token needs api:use.

Parameters

Name In Type Required Description
account path string (uuid) Yes The account's id.
space query string (uuid) No The id of the space to work in (see GET /spaces). Defaults to your personal space. On writes it may also be sent in the JSON body.

Response

200

Field Type Description
data Account
data.id string (uuid) The account's id.
data.space_id string (uuid) or null The id of the space the account is in.
data.name string The account's name.
data.type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" The account type. checking, credit_card, savings and others keep a transaction ledger; investment, retirement, loan and real_estate track a balance only.
data.currency string The ISO 4217 currency the account is held in, which its amounts are in.
data.bank object or null The bank the account is held at, if one is set: its id and name.
data.bank.id string
data.bank.name string
data.is_connected boolean Whether the account is connected to a bank. A connected account's balances, currency and bank come from the sync: only its name, type and ownership can be changed, and it takes no manual balance.
data.ownership_percentage integer The owner's share of the account, 1 to 100. Below 100 only that slice counts in their figures.
data.ownership_applies_to_balance boolean Whether the ownership share applies to the balance too, not only to transactions.
data.credit_card_detail object or null credit_card only, otherwise null: the card's limit and statement dates, in minor units and ISO dates. Later cycles repeat from the dates at statement_frequency. null while none is set.
data.credit_card_detail.statement_closing_date string or null
data.credit_card_detail.payment_due_date string or null
data.credit_card_detail.statement_frequency "monthly" | "weekly"
data.credit_card_detail.credit_limit integer or null
data.credit_card_statement object or null credit_card only, otherwise null: an estimate of the card's next charge, computed from its statement dates and its transactions. It is not a transaction, and next_payment.is_final is false while the cycle is still open. null while the card has no statement dates.
data.credit_card_statement.next_payment object
data.credit_card_statement.next_payment.period_from string
data.credit_card_statement.next_payment.closing_date string
data.credit_card_statement.next_payment.due_date string
data.credit_card_statement.next_payment.amount integer
data.credit_card_statement.next_payment.is_final boolean
data.credit_card_statement.next_payment.paid integer
data.credit_card_statement.current_cycle object
data.credit_card_statement.current_cycle.period_from string
data.credit_card_statement.current_cycle.closing_date string
data.credit_card_statement.current_cycle.due_date string
data.credit_card_statement.current_cycle.amount integer
data.credit_card_statement.payments array of object
data.credit_card_statement.payments[].transaction_id string
data.credit_card_statement.payments[].date string
data.credit_card_statement.payments[].amount integer
data.credit_card_statement.payments[].period_from string
data.credit_card_statement.payments[].closing_date string
data.credit_card_statement.payments[].due_date string
data.credit_card_statement.previous_statement object
data.credit_card_statement.previous_statement.period_from string
data.credit_card_statement.previous_statement.closing_date string
data.credit_card_statement.previous_statement.due_date string
data.credit_card_statement.previous_statement.purchases integer
data.credit_card_statement.previous_statement.paid integer
data.credit_card_statement.previous_statement.pending integer
data.credit_card_statement.previous_statement.has_recorded_purchases boolean
data.credit_card_usage object or null credit_card only, otherwise null: how much of the card is in use. used is what is still to be charged between period_from and today, less the payments made on those statements, never below 0. available is limit minus it, negative over the limit; both limit and available are null while no credit limit is set.
data.credit_card_usage.limit integer or null
data.credit_card_usage.used integer
data.credit_card_usage.available integer or null
data.credit_card_usage.period_from string
data.credit_card_usage.period_to string
data.archived_at string (date-time) or null When the account was archived in the app, or null. An archived account keeps its history and still answers here.
data.created_at string (date-time) or null When the account was created.

Example request

curl https://whisper.money/api/v1/accounts/0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60 \
  -H "Authorization: Bearer $WHISPER_MONEY_TOKEN"

Example response

{
    "data": {
        "id": "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01",
        "space_id": "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60",
        "name": "Main checking",
        "type": "checking",
        "currency": "EUR",
        "bank": {
            "id": "0199a3f1-5b2c-7e8d-9f0a-1b2c3d4e5f60",
            "name": "BBVA"
        },
        "is_connected": false,
        "ownership_percentage": 100,
        "ownership_applies_to_balance": true,
        "credit_card_detail": null,
        "credit_card_statement": null,
        "credit_card_usage": null,
        "archived_at": null,
        "created_at": "2026-01-15T09:30:00+00:00"
    }
}

Errors

Status When
401 No bearer token, or one that is unknown, expired or revoked.
403 The token lacks the scope (insufficient_scope), the account has no Pro plan (plan_required, with a subscribe_url) or it is a shared demo account (shared_account).
404 No object with that id exists, or it belongs to someone else.
422 The request failed validation.
429 The rate limit is exhausted. Wait the seconds in Retry-After.

Update an account

PATCH /api/v1/accounts/{account}

Changes only the fields you send. On a manual account that is all of them; on a bank-connected one only the name, the type (among checking, credit_card, savings and others) and the ownership fields, since its currency and bank come from the bank. A loan with no details yet needs annual_interest_rate, loan_term_months and original_amount together; sending only some of them is a 422 and nothing in the request is saved. Changing a loan or a property to another type keeps its details and any mortgage link on file but stops using them. Archiving, hiding and deleting an account happen in the app.

Scope: write. A personal token needs api:write (a read & write token); an OAuth token needs api:use.

Parameters

Name In Type Required Description
account path string (uuid) Yes The account's id.
space query string (uuid) No The id of the space to work in (see GET /spaces). Defaults to your personal space. On writes it may also be sent in the JSON body.

Request body

Field Type Required Description
name string No The account's new name. The sync never rewrites it, so a bank-connected account can be renamed too.
type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" No The new account type. On a bank-connected account only checking, credit_card, savings and others are possible: the rest keep no transaction ledger for the sync to write into.
currency_code "USD" | "EUR" | "GBP" | "JPY" | "CHF" | "CZK" | "CAD" | "AUD" | "NZD" | "CNY" | "INR" | "PKR" | "MXN" | "ARS" | "BOB" | "CLP" | "PYG" | "PEN" | "UYU" | "VES" | "BRL" | "COP" | "DOP" | "SAR" | "KWD" | "BTC" | "RSD" | "NGN" | "GHS" | "SEK" | "GTQ" | "HNL" | "HKD" | "THB" | "DKK" | "SGD" No The new ISO 4217 currency. Refused on a bank-connected account, whose currency comes from the bank.
bank_id string or null No The new bank id, or null to clear it. Refused on a bank-connected account, whose bank comes from the connection.
ownership_percentage integer No Your share of the account, 1 to 100. Below 100 only that slice counts in your figures, and the budgets that already counted the account are reweighed.
ownership_applies_to_balance boolean No Whether the ownership share applies to the balance too, not only to transactions.
property_type "residential" | "commercial" | "land" | "vacation" | "other" No real_estate only: what kind of property it is. Required when the property's details are first created.
address string or null No real_estate only: the property's address.
purchase_price integer or null No real_estate only: what it was bought for, in minor units. With purchase_date and a balance, the value history in between is filled in.
purchase_date string (date) or null No real_estate only: when it was bought. Not in the future, not before 1900.
area_value number or null No real_estate only: floor area, in area_unit.
area_unit "sqm" | "sqft" | "acres" | "hectares" | null No real_estate only: the unit of area_value.
revaluation_percentage number or null No real_estate only: expected yearly revaluation, as a percentage.
notes string or null No real_estate only: free-text notes on the property.
linked_loan_account_id string (uuid) or null No real_estate only: id of one of your loan accounts that is this property's mortgage.
annual_interest_rate number or null No loan only: yearly interest rate, as a percentage.
loan_term_months integer or null No loan only: the term, in months.
original_amount integer or null No loan only: the amount originally borrowed, in minor units. A loan's details are created once annual_interest_rate, loan_term_months and original_amount are all known.
loan_start_date string (date) or null No loan only: when the loan started. Defaults to today.
statement_closing_date string (date) or null No credit_card only: a statement closing date. Later cycles repeat from it at statement_frequency. Send it with payment_due_date; both null clears them.
payment_due_date string (date) or null No credit_card only: when that statement is charged. On or after the closing date, at most 45 days later on a monthly card and 7 on a weekly one.
statement_frequency "monthly" | "weekly" | null No credit_card only: how often a statement closes. Left out, the stored one stays (monthly on a new card).
credit_limit integer or null No credit_card only: the card's credit limit, in minor units. null clears it.

Response

200

Field Type Description
data Account
data.id string (uuid) The account's id.
data.space_id string (uuid) or null The id of the space the account is in.
data.name string The account's name.
data.type "checking" | "credit_card" | "investment" | "loan" | "retirement" | "real_estate" | "savings" | "others" The account type. checking, credit_card, savings and others keep a transaction ledger; investment, retirement, loan and real_estate track a balance only.
data.currency string The ISO 4217 currency the account is held in, which its amounts are in.
data.bank object or null The bank the account is held at, if one is set: its id and name.
data.bank.id string
data.bank.name string
data.is_connected boolean Whether the account is connected to a bank. A connected account's balances, currency and bank come from the sync: only its name, type and ownership can be changed, and it takes no manual balance.
data.ownership_percentage integer The owner's share of the account, 1 to 100. Below 100 only that slice counts in their figures.
data.ownership_applies_to_balance boolean Whether the ownership share applies to the balance too, not only to transactions.
data.credit_card_detail object or null credit_card only, otherwise null: the card's limit and statement dates, in minor units and ISO dates. Later cycles repeat from the dates at statement_frequency. null while none is set.
data.credit_card_detail.statement_closing_date string or null
data.credit_card_detail.payment_due_date string or null
data.credit_card_detail.statement_frequency "monthly" | "weekly"
data.credit_card_detail.credit_limit integer or null
data.credit_card_statement object or null credit_card only, otherwise null: an estimate of the card's next charge, computed from its statement dates and its transactions. It is not a transaction, and next_payment.is_final is false while the cycle is still open. null while the card has no statement dates.
data.credit_card_statement.next_payment object
data.credit_card_statement.next_payment.period_from string
data.credit_card_statement.next_payment.closing_date string
data.credit_card_statement.next_payment.due_date string
data.credit_card_statement.next_payment.amount integer
data.credit_card_statement.next_payment.is_final boolean
data.credit_card_statement.next_payment.paid integer
data.credit_card_statement.current_cycle object
data.credit_card_statement.current_cycle.period_from string
data.credit_card_statement.current_cycle.closing_date string
data.credit_card_statement.current_cycle.due_date string
data.credit_card_statement.current_cycle.amount integer
data.credit_card_statement.payments array of object
data.credit_card_statement.payments[].transaction_id string
data.credit_card_statement.payments[].date string
data.credit_card_statement.payments[].amount integer
data.credit_card_statement.payments[].period_from string
data.credit_card_statement.payments[].closing_date string
data.credit_card_statement.payments[].due_date string
data.credit_card_statement.previous_statement object
data.credit_card_statement.previous_statement.period_from string
data.credit_card_statement.previous_statement.closing_date string
data.credit_card_statement.previous_statement.due_date string
data.credit_card_statement.previous_statement.purchases integer
data.credit_card_statement.previous_statement.paid integer
data.credit_card_statement.previous_statement.pending integer
data.credit_card_statement.previous_statement.has_recorded_purchases boolean
data.credit_card_usage object or null credit_card only, otherwise null: how much of the card is in use. used is what is still to be charged between period_from and today, less the payments made on those statements, never below 0. available is limit minus it, negative over the limit; both limit and available are null while no credit limit is set.
data.credit_card_usage.limit integer or null
data.credit_card_usage.used integer
data.credit_card_usage.available integer or null
data.credit_card_usage.period_from string
data.credit_card_usage.period_to string
data.archived_at string (date-time) or null When the account was archived in the app, or null. An archived account keeps its history and still answers here.
data.created_at string (date-time) or null When the account was created.

Example request

curl -X PATCH https://whisper.money/api/v1/accounts/0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60 \
  -H "Authorization: Bearer $WHISPER_MONEY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Joint checking",
    "ownership_percentage": 50
}'

Example response

{
    "data": {
        "id": "0199a3f4-1d2e-7c3b-8a4f-5e6d7c8b9a01",
        "space_id": "0199a3f2-6c1e-7b4d-9a8e-2f5c1d3b4a60",
        "name": "Main checking",
        "type": "checking",
        "currency": "EUR",
        "bank": {
            "id": "0199a3f1-5b2c-7e8d-9f0a-1b2c3d4e5f60",
            "name": "BBVA"
        },
        "is_connected": false,
        "ownership_percentage": 100,
        "ownership_applies_to_balance": true,
        "credit_card_detail": null,
        "credit_card_statement": null,
        "credit_card_usage": null,
        "archived_at": null,
        "created_at": "2026-01-15T09:30:00+00:00"
    }
}

Errors

Status When
401 No bearer token, or one that is unknown, expired or revoked.
403 The token lacks the scope (insufficient_scope), the account has no Pro plan (plan_required, with a subscribe_url) or it is a shared demo account (shared_account).
404 No object with that id exists, or it belongs to someone else.
422 The request failed validation.
429 The rate limit is exhausted. Wait the seconds in Retry-After.