← AIron

AIron API for AI assistants

Let ChatGPT, Claude, a shortcut or your own script log workouts, cardio, meals and body measurements straight into a user's AIron account. Scoped tokens, no password sharing, no browser automation.

The 30-second version — paste this to your AI

If you use ChatGPT, Claude or another assistant, copy this block into the chat. Any capable agent can take it from there — it will ask AIron for a connection, show you a link to approve, and start logging.

Connect my AIron account so you can log and read my training and nutrition.

1. Call POST https://airon.app/api/functions/authorizeApiClient with
   {"action":"start","client_name":"<your app name>"} and show me the connect_url.
2. When I say I've approved, collect my token with
   {"action":"poll","device_code":"<device_code from step 1>"}.
3. From then on call the REST API at https://airon.app/api/functions/apiV1
   (plain GET on that URL describes every endpoint) or the MCP server at
   https://airon.app/api/functions/mcp — with "Authorization: Bearer <token>".
Full machine-readable guide: https://airon.app/llms.txt

1. Connect an account

The pairing flow is the recommended path: your app never sees a password and the user never copies a secret between windows. Start it with no authentication at all.

POST https://airon.app/api/functions/authorizeApiClient
Content-Type: application/json

{"action":"start","client_name":"ChatGPT","scopes":["workouts:write","nutrition:write"]}

You get back a connect_url and a private device_code. Send the user to the URL — they approve on a screen that names your app and lists exactly what you asked for — then poll every 3 seconds until the token appears.

POST https://airon.app/api/functions/authorizeApiClient
{"action":"poll","device_code":"airon_dev_…"}

202 → {"status":"authorization_pending"}   keep waiting
200 → {"access_token":"airon_pat_…"}       store it, shown once
410 → expired / already claimed          start over

Codes expire after 15 minutes. Tokens minted through pairing never expire. A user can also mint a token by hand at /ApiAccess.

2. Authenticate

Authorization: Bearer airon_pat_…

The token is the identity. There is no user or email parameter anywhere in this API — sending one has no effect. Each token carries only the scopes its owner granted; a call outside them returns 403 naming the missing scope so you can tell the user what to enable. Limit: 120 requests per minute.

3. MCP server (ChatGPT / Claude connectors)

Paste this URL as a custom connector in ChatGPT (Settings → Connectors → Add) or Claude (Settings → Integrations → Add custom connector). It speaks JSON-RPC 2.0 — initialize, tools/list, tools/call — and only lists the tools your token is allowed to use, so the model never sees an affordance it will be refused on.

https://airon.app/api/functions/mcp

The connector will ask for a token. The clean way to get one is the pairing flow in section 1 — tell the assistant to run it before you add the connector, or mint one manually at /ApiAccess and paste it.

4. REST endpoints

Base URL https://airon.app/api/functions/apiV1. A plain GET on the base URL returns a machine-readable index with the JSON schema of every endpoint — point an agent at it and it can discover the whole API by itself. An OpenAPI 3.1 document lives at ?path=/openapi.json.

Send the resource in the path query parameter; filters, dates and ids ride as ordinary siblings of it:

GET    …/apiV1?path=/workouts&from=2026-08-01&to=2026-08-07
GET    …/apiV1?path=/meals&date=2026-08-03
POST   …/apiV1?path=/meals            {"items":[…]}
DELETE …/apiV1?path=/meals/<id>

Sub-paths such as …/apiV1/workouts are not routed by the host and return 404 — always use ?path=.

Call as {base}?path=/workouts — the resource goes in the path query parameter.

MethodPathScopePurpose
GET/profileprofile:readGoals, units, daily calorie and macro targets
GET/workoutsworkouts:readList sessions and plans in a date range
GET/workouts/{id}workouts:readOne session with every set and interval
POST/workoutsworkouts:writeLog a workout — strength, cardio, rest, RPE
PATCH/workouts/{id}workouts:writeEdit a session
DELETE/workouts/{id}workouts:writeSoft-delete a session
GET/mealsnutrition:readMeals with daily totals
POST/mealsnutrition:writeLog food — one entry per item
DELETE/meals/{id}nutrition:writeDelete a meal entry
POST/waternutrition:writeLog hydration in millilitres
GET/metricsmetrics:readWeight, body fat, circumferences, photos
POST/metricsmetrics:writeLog a measurement or progress photo
DELETE/metrics/{id}metrics:writeDelete a measurement

5. Units — convert before sending

  • Weight in kilograms, body lengths in centimetres.
  • Distance in metres (5 km → 5000), pace in seconds per km (5:30/km → 330).
  • Durations and rest in seconds, dates as YYYY-MM-DD.
  • GET /profile returns the user's display preference so you can speak in their units while sending canonical ones.

6. Log a workout

Send one entry per set — three sets of bench press are three entries. Cardio intervals live in the same array with an activity_type.

curl -X POST "https://airon.app/api/functions/apiV1?path=/workouts" \
  -H "Authorization: Bearer airon_pat_…" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "2026-08-02",
    "title": "Push day",
    "exercises": [
      {"exercise_name":"bench press","set_number":1,"reps":8,"weight":80,"rpe":7,"rest_seconds":120},
      {"exercise_name":"bench press","set_number":2,"reps":8,"weight":80,"rest_seconds":120},
      {"exercise_name":"treadmill run","activity_type":"run","set_number":1,
       "distance_m":5000,"duration_seconds":1500,"avg_hr":152}
    ]
  }'

Add "completed": false to create a planned session for a future date instead of a performed one.

7. Recipes

Log training from ChatGPT or Claude

Paste the 30-second block at the top, approve the connection, then just talk: "log 3×8 bench at 80 kg and a 5k run in 25 minutes". The assistant converts units, splits sets, and shows you a link to the logged session. Add the MCP URL as a connector for the smoothest experience.

Siri / Apple Watch via Shortcuts

Mint a token at /ApiAccess with nutrition:write only. Shortcut: Dictate Text → Get Contents of URL (POST to …/apiV1?path=/water with the Bearer header and {"amount_ml":250}). One tap on the watch face logs a glass of water; same pattern works for weight every morning.

Nightly sync into a spreadsheet or dashboard

A cron script with a read-only token: GET ?path=/workouts&from=…&to=…, GET ?path=/meals&date=… and GET ?path=/metrics give you everything for a personal Grafana sheet or a coach's weekly review — no CSV exports.

Your own agent or app

Point any LLM at GET on the base REST URL — the discovery document is the contract: endpoints, schemas, units, error codes. The agent needs nothing else to operate the API correctly.

8. Reauth, rescope, revoke — the token lifecycle

If the token stops working (reauth)

Tokens are bearer secrets, not sessions — there is no refresh flow by design. A 401 carries a machine-readable reason: invalid_token, revoked_token or expired_token. The answer is always the same: start a new pairing (section 1) and have the user approve again — 30 seconds, and only the human can do it. Lost tokens cannot be recovered (only hashes are stored), so a lost token is revoked and replaced, never "found".

If you need more (or fewer) permissions — rescope

Two ways. The user can edit a token in place at /ApiAccess (pencil icon): toggle permissions, save — the token string does not change, so nothing has to be re-pasted anywhere; the new permissions apply from the next request. Or the app can start a fresh pairing requesting the extra scopes, which mints a new token — swap it in and the user can revoke the old one.

A 403 insufficient_scope response names the missing scope in required_scope — tell the user exactly which permission to enable. Do not retry in a loop.

Revoke

Any token dies instantly at /ApiAccess; the very next request with it returns 401 revoked_token. The user also gets an email the first time a new token is used, so a silent connection cannot stay silent.

9. Errors an agent can act on

Every error body is {"ok":false,"error":<code>,"message":<for the user>}. The error code is stable — branch on it, not on the message text.

CodeHTTPWhat to do
missing_token / invalid_token401You have no usable credential. Run the pairing flow (section 1).
revoked_token / expired_token401The credential is dead. Re-pair; the user must approve again.
insufficient_scope403Read required_scope, ask the user to enable it at /ApiAccess. Never retry in a loop.
rate_limited429Wait retry_after_seconds, then resume.
unknown_endpoint404Wrong path — GET the base URL for the index. Use ?path=, not sub-paths.
not_found404That id does not exist on this account (or is not yours — they look identical on purpose).
api_write_unavailable503Temporary server-side condition; reads still work. Try later.
internal_error500Nothing was saved. Retry once; if it persists, report it.

Safety and privacy

  • Tokens are stored only as SHA-256 hashes — AIron cannot show a token again, and a database leak cannot be replayed.
  • A user can revoke any token instantly at /ApiAccess; access stops on the next request.
  • Deleting a workout is reversible (soft delete); deleting a meal or measurement is not.
  • This API reaches health data. Read the privacy policy before connecting a third-party assistant.