TimalioHelpAPI and MCP server

API and MCP server

Everything the interface does can be done from the API, and an AI plugged into the MCP server schedules posts that go through the same approval as yours.

The key

An admin creates it under API. It carries a role (the same roles as the team) and acts on behalf of its creator. Give it the weakest role that is enough.

The key is shown only once, when it is created. After that the database only keeps its fingerprint. Lost, it gets revoked and created again.

A key cannot create another key, manage the team, commit money, export the data or delete an organization. Those need a real browser session.

An example that works

List your connected accounts, to get their ids:

curl https://app.timalio.com/api/v1/accounts \
  -H "Authorization: Bearer tml_YOUR_KEY"

Create a post:

curl https://app.timalio.com/api/v1/posts \
  -H "Authorization: Bearer tml_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{"text":"Hello",
       "accounts":["<account id>"],
       "scheduledAt":"2026-10-01T09:00:00Z"}'

The post is created as a draft (its state reads BROUILLON in the response). It will not go out until it has been submitted and approved.

Submit it for approval:

curl https://app.timalio.com/api/v1/posts/<id>/action \
  -H "Authorization: Bearer tml_YOUR_KEY" \
  -H "content-type: application/json" \
  -d '{"action":"SUBMIT"}'

What is exposed

PathWhat it does
GET /api/v1/accountsConnected accounts and their ids
GET /api/v1/postsThe queue: 200 newest by default. Optional `since`, `until` (ISO 8601), `state` (comma-separated), `limit` (1 to 500) and `before` (the `suivant` cursor of the previous page, null on the last); an unknown parameter is a 400. The MCP `list_posts` tool takes the same
POST /api/v1/postsCreate a post, as a draft
GET /api/v1/posts/<id>Read one post
POST /api/v1/posts/<id>/actionSubmit, approve, request changes, move, delete
GET /api/v1/posts/<id>/logWho did what, and when
POST /api/v1/imagesUpload an image
POST /api/v1/videosUpload a video (file or public URL)
GET /api/v1/slotsThe organization’s slots, and its time zone
POST /api/v1/slots/nextThe next free slot across accounts
POST /api/v1/import/previewRead a file back without writing anything
POST /api/v1/import/confirmWrite the import, all or nothing
GET /api/rulesEach network’s up-to-date rules

The actions available on a post are SUBMIT, APPROVE, REQUEST_CHANGES, EDIT, RESCHEDULE, SCHEDULE_DIRECTLY and DELETE. These are the same functions as the interface, not a second set of rules: a limit fixed on one side is fixed on the other.

An unknown field in a write request (for example `format_instagram` instead of the documented name `formatInstagram`) is refused with a 400 that names it and suggests the right name: nothing is ever ignored silently.

Watch two fields that do not behave the same when editing a post: sending `accounts` or `images` replaces what was there, so an empty array clears everything; not sending `variants` keeps them, and only `{}` erases them. Fixing a typo in the common text must not silently erase the adaptation somebody else wrote.

Rate limits

A few routes are capped per organization, on a rolling ten-minute window, to protect Timalio’s own disk and the third parties it calls on your behalf. A refusal answers 429 with a `Retry-After` header, in seconds: the exact time left before the next attempt is allowed, and the error message states the same delay in minutes.

  • Uploading an image or a video, directly or through the MCP tools `upload_image`/`upload_video`: 60 per organization every 10 minutes.
  • Fetching an image or a video by `url` instead of uploading it counts against its own, stricter cap: 20 per organization every 10 minutes.
  • Reading back or writing a CSV import (`/api/v1/import/preview` and `/api/v1/import/confirm` share one counter): 20 per organization every 10 minutes.
  • Verifying a Discord webhook, a Mastodon instance or a Telegram chat: 30 per organization every 10 minutes.

English names, French names

Timalio was first written in French, and every name on this page has a French twin. Both are accepted, everywhere, for good: a request may use one or the other, field by field. Sending both names of the same field is fine when the two values are equal, and refused (400) when they differ, naming the two fields. Nothing is picked for you in silence.

EnglishFrench
texttexte
accountscomptes
scheduledAtprogrammeLe
firstCommentpremierCommentaire
variantsvariantes
commentcommentaire
contentcontenu
altTexttexteAlternatif
coverOffsetMscouvertureOffsetMs
coverImagecouvertureImage
dayjour
lineslignes
thensuite
SUBMITSOUMETTRE
APPROVEVALIDER
REQUEST_CHANGESDEMANDER_REPRISE
EDITMODIFIER
RESCHEDULEREPROGRAMMER
SCHEDULE_DIRECTLYPROGRAMMER_DIRECTEMENT
DELETESUPPRIMER
DRAFT, SCHEDULE (import)BROUILLON, PROGRAMMER
/api/v1/accounts/api/v1/comptes
/api/v1/slots/api/v1/creneaux
/api/v1/slots/next/api/v1/creneaux/prochain
/api/v1/import/preview/api/v1/import/apercu
/api/v1/import/confirm/api/v1/import/confirmer
/api/v1/import/example/api/v1/import/exemple
…/posts/<id>/log…/posts/<id>/journal
…/posts/<id>/comment…/posts/<id>/commentaire
…/posts/<id>/duplicate…/posts/<id>/dupliquer
/api/rules/api/regles
network_rulesregles_du_reseau
list_accountslister_comptes
list_postslister_posts
read_postlire_post
schedule_postprogrammer_post
act_on_postagir_sur_post
upload_imageenvoyer_image
retry_commentrelancer_commentaire
prepare_connectionpreparer_connexion
cart_statusetat_panier
cancel_connectionannuler_connexion

Responses keep their French names, whatever you send: `texte`, `etat`, `programme_le`, and values such as BROUILLON (draft), EN_ATTENTE (awaiting approval), PROGRAMME (scheduled), PUBLIE (published). One stable shape: a response that changed with the request would break whoever reads back what they wrote. Error messages, on the other hand, come in the language of the key’s owner. Two outputs can be asked for in English with `?names=en`: the MCP tool list, and the header row of the CSV export.

The MCP server

The same key plugs an AI into Timalio. It finds fourteen tools there: read a network’s up-to-date rules, list accounts, list and read posts, schedule one or publish it now, act on a post, upload an image or a video, retry a first comment, and prepare the connection of a new account (below).

{
  "mcpServers": {
    "timalio": {
      "url": "https://app.timalio.com/api/mcp?names=en",
      "headers": { "Authorization": "Bearer tml_YOUR_KEY" }
    }
  }
}

HTTP transport. With `?names=en` the tools are listed under their English names, with English arguments; without it, under the French ones. Calls accept both. Each network’s rules are served in the language of the key’s owner.

A post created by an AI does not go out on its own. It is born a draft and follows the same loop as any other: it has to be submitted, and somebody has to approve it. That is the whole point of the loop: an AI that publishes without review is exactly what we do not want to sell.

Adding an account from an AI

`prepare_connection` lets an AI add an account, within two limits it cannot lift: it never gives consent, and it never pays. For the networks that sign in through their own approval screen, it gets a link that works once, for 24 hours. The AI hands it to the owner of the account, who needs no Timalio account: the page shows which organization is asking, then sends them to the network’s own approval screen. For a Discord channel, the AI gives its webhook and the channel is connected after the same checks as the Accounts page. The tool says which networks it handles; the others are connected from the Accounts page.

An account the subscription does not cover yet is not refused: it goes to the cart, inactive, for seven days. `cart_status` gives the AI the accounts waiting, the monthly amount they add and a link to the Accounts page, where an administrator, signed in, reviews the amount and pays. Nothing is charged before that click. An exempt organization has no cart.

Only an ADMIN key creates a link, and only while its owner is still an administrator. At most 10 links per organization over 24 hours. Each link appears on the Accounts page, with what became of it, and can be revoked there or with `cancel_connection`; revoking the key ends its links too. Send a link only to the owner of the account: whoever opens it first can connect their own account with it.

See also

A question this page doesn’t answer? contact@timalio.com

Back to the help index