# The Ondes PRO REST API

> Ondes PRO REST API v1: ~135 resources, scoped API keys, an OpenAPI 3.1 schema, idempotency, cursor pagination, signed webhooks and a payments test mode.

Updated on 2026-10-21 · The Ondes PRO team · https://ondes.pro/en/integrations/rest-api

Every Ondes PRO workspace exposes a **versioned REST API** under `/api/v1/`: products, orders, stock, quotes, invoices, CRM records, Kanban cards, calendar events and more. Around **135 resources**, documented from your workspace’s real routes, with scoped API keys, an **OpenAPI 3.1** schema, signed webhooks and a test mode for risk-free payments.

## Your first Ondes PRO REST API call

Create a key under **Admin → API & Developers → API keys**, then send it in the `Authorization` header. This call lists invoices past their due date and keeps only three fields.

```bash
curl "https://your-workspace.ondes.pro/api/v1/billing/factures/?statut=en_attente&date_echeance__lt=2026-10-21&fields=numero,date_echeance,etat" \
  -H "Authorization: ApiKey opk_…"
```

The key is shown only once, when you create it. Keep it in a secrets manager.

## How to authenticate: API key, JWT or session

An **API key** (`Authorization: ApiKey opk_…`) carries **scopes** shaped `module:action`, such as `billing:read`. A scope is a ceiling: access requires the scope **and** the module permission in the holder’s role. A key can therefore never outreach the person who created it, and each key has its own per-minute quota.

A handful of resources never accept a key, because they touch permissions themselves (roles) or end-to-end encrypted content (messaging). Those need a JWT or an admin session. Each resource sheet says so, and the API answers with an explicit refusal rather than an empty result.

## How API v1 keeps you out of trouble

- **Idempotency**: an `Idempotency-Key` header makes a create safe to replay after a network drop, with no duplicate.
- **Pagination** by page (50 rows by default, 200 at most) or **by cursor** with `?pagination=curseur`, to walk large datasets without drift.
- **`expand` and `fields`**: embed a relation in the same response, or receive only the columns you need.
- **Structured errors**: every refusal carries an `ondes_erreur` block with a stable `code` and a `reessayable` (retryable) flag.
- **Visible rate limits**: `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers, plus `Retry-After` when you need to wait.
- **Multi-company**: each request runs inside one company, and a subsidiary never reads a sister company’s data.

## Receive signed webhooks when an order is paid

Instead of polling, subscribe a URL to the events you care about through the `developer/abonnements` resource. Every delivery carries an `Ondes-Signature` header (timestamp plus an HMAC-SHA256 of the body), following the pattern developers already know from Stripe. The signing secret is shown only at creation.

The destination is checked before it is saved, and each subscription keeps a delivery log. If your server was down, you can see what failed and replay a delivery, rather than resyncing by hand.

> **A test mode chosen by the URL** — Resources that take money or send messages have a twin under `/api/v1/test/`: an order there creates a simulated payment, with a mock checkout page, no Stripe involved and no effect on your revenue. The mode comes from the address you call, never from a parameter, so nobody goes live by accident.

## Writing a connector from your workspace’s own docs

_Example conversation · demo data (Atelier Lumen)_

> **You** : Write a function that records a parcel’s tracking number on the matching order.
>
> 🔧 `ondes_chercher` Searches “shipment”: finds the `orders/expeditions` resource and the guide section on idempotency.
>
> 🔧 `ondes_ressource` Reads the `orders/expeditions` sheet: required fields, filters, required scope.
>
> 🔧 `ondes_appeler` `POST orders/expeditions` with `simuler: true` — the body is valid, nothing written.
>
> **Assistant** : The function is ready and its payload has been validated against your workspace. I added an idempotency key derived from the tracking number, so a retry never creates two shipments. You will need a key carrying the scope listed on the sheet.

## Where are the docs and the OpenAPI schema?

In your admin, **API & Developers** brings together the guide, a route explorer, the downloadable OpenAPI 3.1 schema, your keys and their usage analytics. Everything is generated by introspecting the real routes, so a resource that does not exist in your workspace is simply not listed.

The same guide is also served on demand by the MCP server, through six documentation tools — including `ondes_impossible`, which lists what the API deliberately does not do. For a full walkthrough, follow the [build an integration](https://ondes.pro/en/integrations/mcp/guides/build-an-integration) guide.

## Go further

- [MCP vs REST API](https://ondes.pro/en/integrations/mcp/mcp-vs-rest-api) — What really sets them apart, when to pick which, and why at Ondes PRO they work together.
- [Build an integration](https://ondes.pro/en/integrations/mcp/guides/build-an-integration) — Scoped keys, signed webhooks, idempotency and test mode for a back office that never creates duplicates.
- [Online store](https://ondes.pro/en/integrations/mcp/modules/online-store) — Orders, catalogue, promo codes and shipments handled by your assistant, in test mode by default.
- [Invoicing](https://ondes.pro/en/integrations/mcp/modules/invoicing) — Quotes, invoices, reminders and credit notes prepared by your assistant, within invoicing rules.

## Frequently asked questions

### Is the REST API included in every plan?

Yes. API v1 and the MCP server come with the Essentiel, Pro and Entreprise plans, with no add-on to enable. See [pricing](https://ondes.pro/en/pricing).

### What is the API base URL?

Your workspace address followed by `/api/v1/`, for example `https://your-workspace.ondes.pro/api/v1/`. Each customer has their own instance, hence their own address.

### How do I limit what an integration can do?

Create a key with only the scopes it needs, for instance `billing:read` for a dashboard. A key manager can also set a key’s per-minute quota, suspend it or revoke it, and every action is logged.

### Can the API cancel an invoice?

No, by design: under French rules an issued invoice cannot be cancelled. The API issues a credit note instead, full or partial, with a mandatory reason, through the `avoir/` action on `billing/factures`.

### Is there an OpenAPI schema?

Yes, in OpenAPI 3.1 format, downloadable from API & Developers. It is generated from your workspace’s real routes, so it is always current.

### Should I pick the API or the MCP server?

You do not have to. The MCP server calls API v1 itself: same routes, same permissions. The API suits unattended syncs, MCP suits working with an AI assistant. See [MCP vs REST API](https://ondes.pro/en/integrations/mcp/mcp-vs-rest-api).
