Skip to content
Nowlark
API reference menu

Plans, audit log and transfer

Plans and billing#

A team is judged by its plan, through one function (plans.effective): active, trialing and comped work until period_end, then for a 14-day grace; past_due gets the same grace; canceled works until period_end; paused and unknown statuses are lapsed. A lapse stops sends and new forms only: members, channels, history and forms already collected stay, and the team drops to the free seat count. Team plans are bought on the web, never in the app.

  • GET /v1/teams/{id}/plan (admin): source, state, seats and seats used, forms, paid-through, grace end. No card or invoice detail is held here.
  • POST /v1/teams/{id}/plan/checkout (owner): returns what the web checkout needs to buy or change the team's plan. The console's Buy or change the plan button uses it. 409 plan_active while the team already has a live subscription.
  • POST /v1/teams/{id}/plan/trial (owner): starts the free trial, once per account, no card and no Upgrade Pass: 5 seats and 1 form for 14 days, then lapsed with no grace. 409 trial_unavailable when the account has had its trial, the team already has a plan, or the owner's Upgrade Pass already covers the team.

Audit log#

GET /v1/teams/{id}/audit?before=<id>&limit=<=100 (admin): who changed what, newest first, with next as the cursor. Every change made through the teams API is logged. A row is written only after a non-read request succeeds, and holds the actor, the route template, and the ids its path named: never a body, so no key, destination target, message or form text. The merchant's webhook and our own tools write rows with a system: actor. The table is append-only (triggers refuse an update, and a delete while the team exists and the row is under 400 days old); deleting the team or its owner's account erases the log with it.

Ownership transfer#

Two steps, so a team is never dumped on someone: the owner offers, one of the team's other admins accepts. POST /v1/teams/{id}/transfer {"to": account_id} (owner; the target must be an admin), DELETE .../transfer (owner withdraws), POST .../transfer/accept and .../transfer/decline (only the named admin), GET .../transfer (admin; pending with you_are_the_one). An offer lasts 7 days. Acceptance applies only while the offer is live and unexpired, the offerer is still the owner and the taker is still an admin; the old owner becomes an admin, the new one becomes the owner, and the offer is cleared in the same step, so the owner and the owner role cannot disagree. Refused with 409: plan_active while a merchant subscription is live (it belongs to whoever pays it: cancel, hand over, subscribe again) and new_owner_cannot_carry_it while billing is not open and the new owner's own Upgrade Pass would not let the team send. That check runs again at acceptance.