# Mobitree API

Mobitree exposes a JSON REST API for authenticated Studio clients and approved
integrations. New integrations should use the stable `v1` base URL:

```text
https://mobitr.ee/api/v1
```

The unversioned `https://mobitr.ee/api` base remains available as a legacy
compatibility alias. Both bases currently implement the same operation contract;
versioned clients receive `X-Mobitree-API-Version: v1` on every response. Future
breaking changes will ship under a new version and will not silently change v1.

The machine-readable contract lives in [`openapi.json`](./openapi.json); this
page explains the conventions that apply to every endpoint.

## Base URL and authentication

Use `https://mobitr.ee/api/v1`. Requests can authenticate with a session cookie,
an `Authorization: Bearer <personal-api-key>` header, or an `X-API-Key` header.
Personal API keys are created in Account and are shown only once. A read-only
key can inspect resources; write requests require an explicitly write-scoped key
and the normal CSRF protection when using a browser session.

```http
GET /api/v1/profile HTTP/1.1
Host: mobitr.ee
Authorization: Bearer <personal-api-key>
Accept: application/json
```

Unauthenticated requests receive `401`. Permission and plan failures use `403`;
validation failures use `422`; stale versioned writes use `409`.

## Response envelope

Successful responses use `{ "ok": true, "data": ... }`. Collection endpoints
may also include `meta.pagination` with `page`, `limit`, `total`, and
`total_pages`. Errors use `{ "ok": false, "errors": ["..."] }` and never expose
database or provider credentials.

## Core workflows

### Sign in

`POST /api/v1/auth/login` accepts `email`, `password`, and optional `remember`.
Accounts protected by an authenticator return a 202 challenge; complete it with
`POST /api/v1/auth/2fa` and a six-digit authenticator or recovery code. Browser
session requests must include the CSRF token used by the Studio form.

### Profiles and links

`GET /api/v1/profile` returns the current profile available to the authenticated
user. `PUT /api/v1/profile` updates public settings and `POST /api/v1/profile/avatar`
replaces the avatar. `GET /api/v1/links` lists links; `POST /api/v1/links` creates one;
`PUT` and `DELETE /api/v1/links/{id}` update or archive an existing link, and
`POST /api/v1/links/reorder` updates order. Link writes create a recovery version
before changing content.

The `kind` field identifies the visual/content card (for example `normal`,
`product`, or a supported business block). Business-card configuration is
validated as an object and returned as `business_block_config`.

### Dynamic profiles, campaigns, and versions

Profile-scoped routes are under `/api/v1/profiles/{profile_id}`. Collaborators can
read resources according to their profile role; mutations require owner,
admin, or editor access and the owner’s plan entitlement. Profile Versions
review and restore are optimistic-lock protected: review before restore, then
submit the returned preview token. A stale review returns 409 without changes.

### Analytics, billing, and administration

Analytics routes return plan-bounded date ranges. Billing routes create Checkout
or Customer Portal sessions and never return payment secrets. `/api/admin/*`
requires platform-admin authentication and is not a substitute for customer
profile access.

## Representative requests

```bash
curl https://mobitr.ee/api/v1/links \
  -H 'Authorization: Bearer <read-only-api-key>'

curl -X POST https://mobitr.ee/api/v1/links \
  -H 'Authorization: Bearer <write-scoped-api-key>' \
  -H 'Content-Type: application/json' \
  -d '{"title":"My site","url":"https://example.com","kind":"normal"}'
```

For support questions, the read-only [`/mcp`](./MCP.md) endpoint can search this
guide and the feature contracts without accessing customer data.
