Skip to content
All pages

Start here

Authentication and abilities

One header, everywhere: a bearer token that belongs to the team and carries exactly the abilities somebody chose to grant it. Nothing on this surface is public.

The credential

Send the token on every request:

Authorization: Bearer wt_9f3kd02m_…

Tokens are issued by a team owner in Settings → API tokens and belong to the team, not to a person: an integration keeps working when whoever set it up moves on. The secret starts with wt_, is shown exactly once at issue, and is stored only as a hash; there is no path that shows it again. Give each integration its own token with the fewest abilities that do the job, and revoke a token the moment its integration is retired. Revocation is recorded rather than erased, so a key seen in a log later is still identifiable.

Three refusals, kept apart

Authentication can fail three different ways, and each answers differently so your handling can too:

  • 401 unauthenticated: the token is missing, unknown, expired or revoked. Rotate the credential.
  • 402 plan_limit: the token is fine, but the plan does not include API access. The message names the tier that would.
  • 403 missing_ability: the token is fine and the plan allows it, but this key was not granted the ability the endpoint requires. required_ability names it.

A 403 is never a tenancy answer. Another team's record is a 404, exactly as if it did not exist, because a distinguishable refusal would confirm the id.

Abilities

Every endpoint declares the ability it requires; the reference states it beside each one, and GET /api/v1 lists every endpoint with whether your token may call it. Reads and writes are split throughout, and PDF export is its own grant: a read-only key should not be able to walk every report a team owns and take a copy of each.

reports:read Read reports

List reports and read their findings, records and coverage.

reports:write Create and delete reports

Request new reports, and delete existing ones.

reports:export Download report PDFs

Download the rendered PDF of a report.

maps:read Read map tiles

Fetch vector map tiles of the weather archive. Not scoped to a team: the archive is public federal record, and a tile is the same answer for everyone.

properties:read Read properties

List the team's saved properties, their contacts, and the storm days on record near each.

properties:write Create and change properties

Save, change and remove properties, and run a report about one.

territories:read Read territories

List the team's territories with their shapes as GeoJSON, and the storm days inside each.

territories:write Create and change territories

Draw, change and remove territories, including submitting a shape as GeoJSON.

exposures:read Read activity

Read every storm day and warning that touched something the team watches.

exposures:write Acknowledge activity

Mark activity as seen, or set it aside.

account:read Read the account ledger

Read the credit balance and its movements, the team's plan and what it holds against its limits, and when monitoring last ran.

integrations:read Read integrations

List where the team's systems are told about storms, and whether the posts arrived.

integrations:write Create and change integrations

Register, change and remove those destinations, post a test to one, and read or rotate its signing secret. The secret verifies every post we make, so this is authority over what a receiver will believe.

Prove it works

The account endpoint is the mirror: it answers with the token you presented, the plan behind it, and what is left to spend. It requires no ability at all, so it is the right first call for a health check.

Retrieve the account

GET /api/v1/account

The credential, the plan, and the limits, before anything is spent.

any valid token

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/account
curl https://titanweather.com/api/v1/account \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "object": "account",
    "team": {
        "name": "North Texas Claims Group",
        "plan": "professional",
        "plan_label": "Professional",
        "on_trial": false,
        "lapsed": false
    },
    "limits": {
        "lookback_years": 10,
        "max_radius_miles": 10,
        "monthly_reports": 25,
        "reports_used": 7,
        "reports_remaining": 18,
        "pdf_export": true
    },
    "credits": {
        "balance": 18,
        "monthly_allowance": 25,
        "used_this_period": 7,
        "renews_at": "2026-09-01T00:00:00Z"
    },
    "token": {
        "name": "Claims intake",
        "prefix": "wt_9f3kd02m",
        "abilities": [
            "reports:read",
            "reports:write",
            "reports:export"
        ],
        "expires_at": null,
        "last_used_at": "2026-08-23T14:02:11Z"
    }
}
esc
move open 72 places