Skip to main content

Users

The account a credential resolves to.

Overview​

A user is a naturali account: an email address, a display name, and the projects it is a member of. It is the identity behind both credential types — a session issued by Auth and an API key — so GET /v1/users/me answers "who am I" the same way whichever one you present.

The email address is the credential, not a profile field: sign-in codes go to it, and it is therefore not editable through this module.

See the OpenAPI spec for the full endpoint and schema reference, or browse it rendered under API Reference → Users.

Data Model​

User​

FieldTypeDescription
idstringPublic user ID (user_ prefix).
emailstringThe address sign-in codes are sent to. Read-only here.
namestring, nullableDisplay name.
email_verifiedbooleanWhether the address has completed a sign-in code exchange.
rolesstring[]Platform roles, from a fixed catalog. Empty for almost every account; admin marks a naturali operator.
created_atstring (date-time)

UserBilling​

Returned by GET /v1/users/me/billing. Not part of the User shape — see Plan and credit.

FieldTypeDescription
planstringThe rung the account is on: free, pro, business or enterprise.
retention_daysinteger, nullableThe longest content-retention window a project of this account may set. null when nothing bounds it.
credit_balance_usdnumberModel credit left, in USD. Negative when the account has overspent.
earned_balance_usdnumberMarketplace earnings, in USD, less withdrawals.
paid_balance_usdnumberWhat may pay a marketplace fee: purchased credit plus earnings, less the usage included and granted credit did not cover and the fees paid.
spend_reconciled_atstring (date-time), nullableWhen spend was last read from the meter. null when it never has been.
storage_gbnumberIndexed storage the account is holding, in the metered gigabytes the ceiling is enforced in.
storage_limit_gbnumber, nullableThe pool the plan allows. null where a contract sets it, or where the plan sets none.
storage_sampled_atstring (date-time), nullableWhen the oldest sample behind storage_gb was taken. null when a project has never been sampled.

TopUp​

Returned by POST /v1/users/me/top-ups. See Buying credit.

FieldTypeDescription
idstringThe payment's or the checkout's ID at the payment provider.
amount_usdnumberWhat is credited once paid, charged in US dollars or its equivalent in reais.
statusstringpaid — the saved card was charged and the credit added. checkout — nothing is charged until the person pays at checkout_url.
checkout_urlstring, nullableThe hosted page that takes the card. null when paid.
expires_atstring (date-time), nullableWhen an unpaid checkout lapses. null when paid.

PaymentMethod​

Returned by GET /v1/users/me/payment-method. See Auto-recharge.

FieldTypeDescription
brandstringCard brand, such as visa.
last4stringLast four digits.
exp_monthintegerExpiry month.
exp_yearintegerExpiry year.
currencystringbrl for a card issued in Brazil, else usd. See Charge currency.
exchange_ratenumber, nullableUnits of currency per US dollar for a charge made now. null while the rate can't be read.

AutoRecharge​

Returned by GET /v1/users/me/auto-recharge.

FieldTypeDescription
enabledbooleanWhether the balance is topped up automatically.
amount_usdnumber, nullableWhat each recharge buys. null while off.
below_usdnumber, nullableThe balance under which a recharge is charged. null while off.
last_attempted_atstring (date-time), nullableWhen a recharge was last charged, whatever its outcome.

UserUsage​

Returned by GET /v1/users/me/usage. See Runs and the allowance.

FieldTypeDescription
cycle_fromstring (date-time)Start of the cycle counted — the first instant of the current UTC calendar month.
runsinteger, nullableRuns this cycle across every project the account pays for. null when a project's meter could not be read.
runs_includedinteger, nullableRuns the plan includes per cycle. null on a contract plan.
projectsProjectRuns[]Per-project breakdown: project_id and its own nullable runs.

Key Concepts​

One identity, two credentials​

GET /v1/users/me resolves a session access token and a nat_sk_… API key to the same account — a project-scoped key included, which resolves to the user who minted it. That makes it the canonical "is this credential live?" probe: a revoked key answers 401, and a valid one answers with the account it belongs to. Create a provider checks a fresh credential with it.

Plan and credit​

GET /v1/users/me/billing answers the figures the platform enforces against:

  • plan gates features and resource counts. A request outside the rung is refused with 403. It is the plan in effect: an upgrade applies at once, a downgrade when the month ends, and until then next_plan names the plan coming. At the turn, active channels past the new allowance are disabled.

  • retention_days is the longest window a project may keep trace and generation content for. A PATCH asking for a wider one is refused with 403 plan_limit_reached naming this same number, so it is worth reading before you set a window rather than after — see Content retention. On a custom plan it is the contract's figure, and null means nothing bounds it.

  • credit_balance_usd is model credit for naturali-managed models. While it is negative, a managed generation is refused with 402 insufficient_credit. A zero balance still generates — the generation that crosses zero is absorbed and settled against the next top-up. Generations on your own provider credentials are billed by your vendor and never touch this balance. A paid plan's included credit is for its share of the month: an upgrade adds the difference for the days left at once, and it expires when the month ends.

  • paid_balance_usd is what pays for priced marketplace listings: purchased credit plus marketplace earnings, less the model usage your included and granted credit did not cover and the fees already paid. Included and granted credit never count, so a call to a priced listing is refused with 402 insufficient_credit while it is zero or less. earned_balance_usd is what your own listings have earned.

  • storage_gb and storage_limit_gb are how much indexed storage the account holds and how much its plan allows. An ingest past the limit is refused with 403 plan_limit_reached and resource: "storage", whose details name both — so this is where to read them before the refusal.

    The figure is the account's, not a project's: the pool is shared across every project the account pays for, so one project may hold all of it. Per project, read the gb_day component of project usage. And it is measured in gigabytes the meter counts — the raw file plus every chunk's text and its embedding vector — so it is not the size of what you uploaded; see Documents.

Storage is only as current as storage_sampled_at, on the same terms: each project's footprint is measured every few minutes rather than on your request, and the timestamp is the oldest of the samples behind the total, because a sum is only as current as its stalest part. null means a project the account pays for has never been sampled — the figure still reports what the known samples add up to, it just is not current as of anything. A brand-new project reads that way until the next measurement.

The balance is only as current as spend_reconciled_at: spend is read from the meter on a schedule rather than per generation, so a very recent generation may not be in the figure yet. Read the two fields together; null means spend has never been read for at least one of the account's projects.

All three are the account's own. The plan that gates a project is that project's billing owner's, so a member of someone else's project reads their own rung here, not that project's.

It is a separate call rather than fields on GET /v1/users/me because the two answer different questions: identity is fixed for the life of a credential, while a balance moves while a session is open.

Buying credit​

POST /v1/users/me/top-ups buys amount_usd of credit, from $5 up, in whole cents. The full amount is added to credit_balance_usd — the card fee is not deducted.

  • With saved_card: true the saved card is charged at once: status is paid and the credit is already in the balance. If the bank asks to confirm the payment, or declines it, nothing is charged and the answer is a checkout instead.
  • Otherwise status is checkout: send the person paying to checkout_url. After paying, the browser returns to Account → Billing in the console. Creating a checkout charges nothing; an unpaid one lapses at expires_at. The card paid with there becomes the account's saved card, replacing any other.

Purchased credit never expires and is not refundable.

Charge currency​

Credit and prices are in US dollars. A card issued in Brazil is charged the equivalent in reais, at the Banco Central's latest closing PTAX selling rate with no spread; every other card pays US dollars. A saved card's currency decides it for every charge on that card: top-ups, auto-recharge, upgrades and statements. The payment page shows reais to a person paying from Brazil.

The balance receives the USD amount either way. A statement keeps the rate of the moment its charge was prepared. While the rate can't be read, a charge in reais answers 503 exchange_rate_unavailable and nothing is charged.

Auto-recharge​

Auto-recharge tops up the balance on a saved card before managed models stop.

  1. POST /v1/users/me/payment-method opens a hosted page that saves a card and charges nothing. Saving another card replaces it.
  2. PUT /v1/users/me/auto-recharge with amount_usd (from $5) and below_usd. It is refused with 409 payment_method_required until a card is saved.

The balance is checked every 15 minutes, and the card is charged at most once an hour. A declined charge turns auto-recharge off and emails the account. DELETE /v1/users/me/payment-method forgets the card and turns auto-recharge off with it.

Runs and the allowance​

A run is one agent generation or one tool call — the unit every plan is priced in. Every tool call counts, including the ones an agent makes inside a generation: a reply that calls three tools is four runs. A client tool, which your own code runs, counts nothing. GET /v1/users/me/usage counts them for the current billing cycle across every project the account is the billing owner of, and reports the number its plan includes.

On Free the allowance is enforced. An account that has used it is refused 403 plan_limit_reached with resource: "runs" on everything that starts a generation and on a direct tool call, on its own provider credential as much as on a managed model, until the month turns or it upgrades — see A plan's run allowance can stop generation. On Pro and Business nothing is refused: runs past the allowance are billed at the overage rate. Enterprise is not counted.

The other thing that stops a managed-model generation is a credit balance below zero — that is credit_balance_usd, a different quantity, and it never applies to your own credential.

This route counts live; the refusal reads a figure counted every few minutes. So the two can differ by a burst: this is the more current number, and the refusal quotes the one it actually enforced.

runs is null when at least one project's meter could not be read. A total missing a project would understate it, and an understated count read against an allowance claims headroom that may not exist, so the answer is "unknown" rather than "fewer" — the projects breakdown names which one could not be counted.

The read asks the meter once per project, so it is heavier than the balance read. Poll it on the order of minutes. For one project's own usage in more detail — by model, agent, provider or day — use GET /v1/projects/{project_id}/usage.

Editing the account​

PATCH /v1/users/me takes name, usage_alerts, or both. At least one is required, so a request that misspelled a field is refused with a 400 instead of answered with a silent 200 that changed nothing. Send name: null to clear the name.

Usage alerts​

With usage_alerts on — the default for a new account — the account is emailed when any of these reaches 75%, 90% and 100%:

ResourceMeasured as
Model creditSpent this month ÷ (spent this month + balance left). A top-up lowers it; a balance at or below zero is 100%.
RunsRuns this month ÷ the runs the plan includes.
Indexed storageThe account's storage ÷ the plan's storage.

Each level is sent once. Falling back below a level — a top-up, the month turning, deleted storage — re-arms it. Figures are read every 15 minutes, so an alert can arrive up to that long after the crossing. A plan with no published figure for a resource is not alerted on it. The same setting is the checkbox under Account → Billing in the console.

Restoring what billing stopped​

When the credit balance goes below zero, or a Free plan's runs for the month run out, the platform stops what would keep spending on its own: schedule triggers are disabled, eval runs cancelled, orchestration runs and workflow tasks paused. Nothing is turned back on for you.

GET /v1/users/me/stops lists each stopped item that is still waiting on you, newest first. For each one:

  • POST /v1/users/me/stops/{stop_id}/restore re-enables the trigger or resumes the run or task. It is refused with 409 stop_ceiling_closed while blocked_by is set — top up for debt, upgrade or wait for the month to turn for run_allowance. A cancelled eval run (restorable: false) is refused with 409 stop_not_restorable: start a new run from its eval instead.
  • DELETE /v1/users/me/stops/{stop_id} stops listing it without turning it back on.

An item you already turned back on yourself is marked restored when you restore it. The same list is under Account → Billing in the console.

Changing the plan​

PUT /v1/users/me/plan takes free, pro or business. GET /v1/users/me/plan/quote says what it would charge now, changing nothing.

  • An upgrade costs the price difference over the rest of the month, in US dollars before any conversion to reais. The saved card is charged at once, the plan applies, and charged_usd says how much. With no saved card, or when the bank asks to confirm the payment or declines it, nothing is charged and checkout_url is a page that charges the upgrade and saves the card: the plan applies once it is paid, and an unpaid page lapses at expires_at. The month's statement nets the payment out as a prepaid line.
  • A downgrade charges nothing and applies when the month ends; next_plan names it until then.

A contract plan answers 409 plan_by_contract: ask us to change it.

Monthly statements​

GET /v1/users/me/statements lists what the account owes for each closed billing month, newest first. A statement is written within an hour of the month closing and never changes. Each has one line per plan held that month, plus a run overage line when runs went past the allowance:

LineAmount
subscriptionThe plan's monthly price × the share of the month it was held (quantity). A sign-up or a plan change mid-month is billed by the time on each plan.
run_overageRuns past the allowance of the highest plan held that month, at that plan's rate per 1,000 runs.
prepaidWhat was already charged at an upgrade that month, as a negative amount.

total_usd is charged to the saved card within an hour of the statement, and payment_status follows it: unpaid until the charge starts (or while no card is saved), processing, then paid or failed. The provider retries a declined charge; when the last retry fails, the plan moves to Free at the end of the month and the account is emailed. A statement is not a tax invoice. A month spent only on Free has no statement; contract plans and storage overage are not stated. GET /v1/users/me/statements/{statement_id} reads one. The same list is under Account → Billing in the console.

Roles​

roles are roles on naturali itself, not on a project — project access is membership. The catalog has one entry today:

RoleGrantsGranted by
adminOperator access to the platform.admin

roles is read-only here: it appears on GET /v1/users/me, and changing it — like everything else done to an account other than your own — needs the admin platform role and an operator route, which this API does not document.

What a user is not​

A naturali user is a tenant of naturali. Access to a project comes from project membership, and who pays for a project is that project's billing owner — a separate column, so a project can be shared without the payer becoming ambiguous.

Examples​

Read the current account​

naturali get-current-user

Set a display name​

naturali update-current-user --name "Ada Lovelace"

Send { "name": null } to clear it again.

Turn usage alerts off​

naturali update-current-user --usage-alerts false

Read the plan and credit balance​

naturali get-current-user-billing

Upgrade to Pro​

naturali get-current-user-plan-quote --plan pro
naturali set-current-user-plan --plan pro

Top up credit​

naturali create-current-user-top-up --amount-usd 50 --saved-card true

Turn on auto-recharge​

naturali create-current-user-payment-method
naturali set-current-user-auto-recharge --amount-usd 20 --below-usd 5

Read this cycle's runs​

naturali get-current-user-usage

Restore what billing stopped​

naturali list-current-user-stops
naturali restore-current-user-stop --stop-id sst_V1StGXR8Z5jdHi6B

List monthly statements​

naturali list-current-user-statements