Skip to content

For developers

Verified

MitoOps has a public interface in three forms over the same normalised data layer. They differ in who asks and what they may do:

Form Direction What it may do
REST API (/api/v1) your program asks read only — answers GET exclusively, no operation changes anything
MCP (/api/mcp) an AI application asks reads the same data and additionally has narrow writes behind sensitive scopes a person grants explicitly: automations:write (a disabled automation draft and a revision of a running one, which a person publishes), coupons:write and coupons:delete (a discount coupon with preview and confirmation), affiliate:write (affiliate programme management: partner account, portal texts, templates, campaigns, document policy), affiliate:approve (a decision on one named commission; payouts stay in the app), availabilities:draft (a proposed change to the availability list, which reaches the shop only when a person approves it in the app) and claims-settings:draft (a proposed change to the claims settings, written only when a person approves it in the app). Also claims-routes:draft, product-content:draft and category-content:draft: a proposed claims return route and proposed product and category texts, written when a person approves them in the app, or immediately if the client deliberately switches on autonomous writing for that area. Nothing else is created or changed over MCP
Outbound webhooks MitoOps sends to you a signed message about an event (order, payment, shipment, stock, invoice, claim) to your endpoint

The interface currently exposes 130 MCP tools (102 read, 28 that write behind sensitive scopes: automation drafts and revisions, discount coupons, affiliate programme management and proposed changes to availability, claims settings and return shipping and to product and category texts, which a person writes by approving them in the app unless the client deliberately switches on autonomous writing for that area), 101 REST endpoints (all read-only) and 32 permission scopes, 13 of them sensitive, across 19 data areas. The numbers are derived from the application catalogue when this page is built; nobody types them.

What you can read over REST and MCP: shops, orders, products and categories, stock with movement history, invoices and credit notes, shipments and delivery statistics, traffic and channels, financial reports and sales, the customer directory and customer analytics in pseudonyms, suppliers, claims with statistics, the affiliate programme, automations, the shops’ availability lists, webhook endpoints and the account plan with its limits.

The endpoint is /api/v1 on your application domain. Calls, parameters, response shape, periods and pagination are in the REST interface. The machine-readable contract is at /api/v1/openapi.json behind the same key; a signed-in person can open it from Settings → API & MCP too. The contract is generated from the same source as the interface, so it cannot drift.

Anything other than GET gets 405 before the server even looks at the key. This is not a temporary restriction — REST v1 has no write calls and the MCP writes were deliberately kept out of it. A proposed availability change can only be read over REST (its status); it cannot be created there.

The endpoint is /api/mcp. MitoOps is a standard remote MCP server (Model Context Protocol, an open, vendor-neutral protocol); any application that supports remote MCP over HTTP with OAuth or an access key can connect. Claude.ai is a production-verified client; the exact steps are in the MCP interface.

MCP tools stand on the same capabilities as REST — it is not a second interface with its own queries. The tool list follows the scopes of the key or consent: a tool outside the scope does not exist for the application. Every tool carries annotations per protocol revision 2026-07-28 (readOnlyHint, destructiveHint, idempotentHint), so the AI application knows whether it is a read or a write.

OAuth — connecting on behalf of a person

Section titled “OAuth — connecting on behalf of a person”

An AI application that supports remote MCP with OAuth does not connect with a key. You give it the /api/mcp address, it sends you to sign in to MitoOps (including the second factor) and on the consent screen you choose what it may read, which shops it covers and which writes it may make (automation drafts, coupons, affiliate programme management, commission decisions, availability change proposals). The application never sees your password.

What is handed over is decided by the signed-in person — and never more than they may see themselves. Whoever has no right to purchase prices cannot pass it on; whoever may not edit automations will not even see the automations:write scope on the consent screen. OAuth consent does not consume an access key from the plan limit, but it requires a plan with API & MCP — without it the consent screen does not open and says why.

Consent can be revoked at any time in Settings → API & MCP, and every access derived from it stops at the same moment.

For a server calling a server, or for your own program:

  1. In the app open Settings → API & MCP and press New key.
  2. Enter a name you will recognise the key by later.
  3. Choose scopes, shops and interfaces (REST, MCP or both).
  4. Choose the validity and create the key.

The key is sent in a header; it is deliberately not accepted in the URL (URLs end up in logs and browser history):

Authorization: Bearer <your key>

A key or consent never sees more than it was granted. The table is derived from the application catalogue:

Scope Access Sensitive What it opens
stores:read read — the list of shops with their code
orders:read read — orders including items; address as country and city only, totals only with reports:read
products:read read — products, categories and the sale price from the product card
invoices:read read — invoices with items, credit notes and proforma invoices
shipping:read read — shipments, tracking events, carriers (without credentials) and delivery statistics
analytics:read read — traffic, channels, search results and order coverage by tracking
search-console:read read — Google Search performance from the synchronized archive: days, queries, pages, countries and devices
inventory:read read — stock levels and the history of stock movements
reports:read read sensitive financial summary of a period (revenue, VAT, costs, result), revenue with comparison and by month, advertising (spend, budget, ROAS, cost of sale, CPA, MER), when orders come in, revenue sources, sales per product, performance per order, customers as pseudonyms and totals in the bulk order listing
purchasing:read read sensitive suppliers, their offers and cost components
claims:read read — claims and returns with links to the order, credit note and return shipment, the case timeline and sent e-mails; statistics and module processes
automations:read read — the catalogue of triggers and actions, the list of automations, their settings, run history and draft validation
automations:write write sensitive creating or editing a disabled automation draft and proposing a change to an enabled automation (revision); only a person in the app can enable a draft or publish a revision, the running automation does not change
webhooks:read read — the event catalogue, endpoints without the secret and the delivery log without bodies
account:read read — the plan, enabled features and limits with current usage
affiliate:read read — the affiliate programme: overview, partners, campaigns, discount codes, conversions, payouts, statistics, settings, documents, public portal, e-mail templates, help articles and code requests; partner contacts only with personal-data:read, bank and tax data never
affiliate:write write sensitive affiliate programme management: partner account decisions (approve, reject, suspend), code request handling, non-financial programme settings, portal texts, help articles, e-mail templates, campaigns and document policy; commission decisions have their own scope, payouts stay in the app
affiliate:approve write sensitive a decision on one affiliate commission by conversion id: approve, reject or cancel (rejection and cancellation with a reason, the partner is e-mailed); a paid commission is never reverted, bulk approval and payouts do not exist externally
customers:read read — the customer directory: pseudonym, shops, country, language, lifetime counts and dates; name, company, e-mail and phone only with personal-data:read, revenue and LTV only with reports:read
coupons:read read — the shop’s discount coupons with discount and validity, platform support, the activation link and its readiness
coupons:write write sensitive creating a coupon on selected shops (an existing one with different parameters is not overwritten without explicit consent)
coupons:delete write sensitive irreversible deletion of a coupon on the selected shop after a preview and explicit confirmation; a coupon with a live dependency (AI Mailing, sign-up window, scheduled campaign, partner) is not deleted
chatbot:read read — web chatbot statistics for a period: teaser impressions and clicks (click rate), chat opens including how they started, conversation and message counts, outcomes, customer ratings, the newsletter sign-up funnel and a deterministic breakdown of conversation topics (shares, products, knowledge-gap candidates) — totals only
chatbot-conversations:read read sensitive customer conversations with the web chatbot: a list with the first question and transcripts with the bot’s answer sources; the customer is only a random conversation key, e-mail, phone and IBAN inside the text only with personal-data:read, otherwise replaced by a placeholder; only within the shop’s retention
availabilities:draft write sensitive a proposed change to the shop’s availability list (create, update, delete) with a preview; it reaches the shop only when a person with the right permissions approves it in the app, otherwise it expires after 24 hours; it changes neither which availability a product has nor stock levels
claims-settings:read read — claim e-mail and document templates, module settings, tags, return shipping and the shop form; no access tokens
claims-settings:draft write sensitive a proposed change to claim processes, statuses, tags and template texts with a preview; it is written only when a person with the right permissions approves it in the app, otherwise it expires after 72 hours; nothing is deleted
claims-routes:draft write sensitive a proposal to create, update, enable or disable a return route, validated like the screen; a person writes it by approving it in the app, or immediately if the client deliberately switched on autonomous writing for that area; never deletes a route
product-content:read read — a product’s description, short description and SEO texts straight from the shop, with a hash and writability for each field
product-content:draft write sensitive proposed new product texts (up to 30 at once), content fields only, never price, stock, code or EAN; a person writes it by approving it, or immediately when autonomous writing is deliberately switched on
category-content:read read — a category’s top and bottom description and SEO texts, with a hash and writability depending on the shop platform
category-content:draft write sensitive proposed new category texts (up to 30 at once), only fields the shop platform can write; a person writes it by approving it, or immediately when autonomous writing is deliberately switched on

Sensitive scopes are not pre-selected on the key screen or on the consent screen — a person has to tick them deliberately. purchase-prices:read and personal-data:read have no tool of their own; they decide about fields in the other responses. A missing field is not zero — it is missing.

Scopes are a public commitment: they change only backwards-compatibly, and a credential issued earlier does not inherit a new scope (scopes are recorded in it by name). That is why an older key or an older consent did not receive personal data when they got a scope of their own on 2 September 2026, and will not receive the draft write either — that needs a new consent or a new key.

A new scope can also be added to an existing key without replacing the key: Settings → API & MCP → Edit scopes. The key value stays the same; the integration using it keeps running and gets the new scope from its next request. The change is made by a person allowed to manage keys; the plan and sensitive scopes are checked the same way as when issuing a key.

The interface returns operational data; personal data only with the personal-data:read scope:

  • Orders and claims without it return only the country and city — not the name, e-mail, phone or street.
  • The customer directory (customers:read) on its own returns only the pseudonym, shops, country, language, counts and dates. Name, company, e-mail, phone and marketing gender are added by personal-data:read, revenue and LTV by reports:read — a field you have no scope for is removed, not zeroed.
  • Customer analytics (customers/performance) has no personal data at all: the customer is a pseudonym (a hash of the e-mail), the same as customerEmailHash on documents and in the directory.
  • Supplier and affiliate partner contacts are behind the same scope.
  • Web chatbot conversations (chatbot-conversations:read, sensitive) carry only a random conversation key — no name, e-mail, IP or cookie. An e-mail, phone or IBAN the customer typed into the text is returned only with personal-data:read; without it a placeholder takes its place.
  • Bank and tax data of partners (IBAN, company and VAT numbers, billing data of payouts), internal notes, passwords and second-factor secrets are never returned — no scope opens them.
  • Webhooks send identifiers and states, not order contents or customer data.

Every call is written to the audit log without input values, only with field names and a fingerprint.

An AI assistant may propose an automation, it may not enable it. With the automations:write scope (sensitive, never pre-selected, offered only to a person with the right to edit automations):

  • automations_create_draft creates a draft in the disabled state — it does not touch the published version, triggers or runs;
  • automations_update_draft edits only a draft nobody has published yet; a draft being edited in the application editor is not overwritten;
  • the draft appears in Automations like any other work in progress, and only a person in the app with the approval right can enable, publish or run it;
  • automations_revision_create_draft proposes a change to a published, even enabled automation as a revision; the running version stays unchanged until a person loads the revision in the editor and publishes it (automations_revision_update_draft, automations_revision_discard_draft).

Values of fields picked from a list in the editor (order status, shipping, payment, claim status…) come from automations_options in the shape the editor stores. A value that does not exist in the shop and placeholder text such as DOPLNIT_… are validation errors, not success.

Creation is idempotent via clientRequestId, an update requires expectedVersion, and both require the catalogVersion from automations_catalog — a stale catalogue is a conflict, not a silent write. A draft that refers to an unknown trigger, a shop outside the scope or someone else’s webhook endpoint is not saved. Details in the MCP interface.

Availability: a proposed change that a person approves

Section titled “Availability: a proposed change that a person approves”

Availabilities are the entries of a specific shop’s availability list that the shop shows next to a product, for example In stock, Backorder or Preorder: a name, a description, restock and delivery time in hours, a meaning for Google Shopping and a colour. They are not stock levels.

  • availabilities_list and GET /availabilities?market= (scope products:read) return the list of one shop; market is required. The manageable field says whether that shop’s list can be changed from MitoOps, and reason says why not: PLATFORMA (the platform cannot do it), BEZ_ROZSIRENIA (a WooCommerce shop without the MitoOps plugin) or PROSTREDIE (writes to shops are switched off in this environment).
  • availabilities_change_draft (MCP only, sensitive scope availabilities:draft) writes nothing to the shop. It validates the change, stores it as a proposal valid for 24 hours and returns a preview (each field before and after, warnings, blocking errors), the draftId and an approvalUrl.
  • The proposal reaches the shop only when a person in the app clicks Approve and write under Warehouse → Availability → Manage, or rejects it. What counts is that person’s permissions at the moment of the click, not the scope of the key or consent. Neither a model nor an access key can write anything to the shop without a person.
  • availabilities_draft_get and GET /availabilities/drafts/:draftId (scope products:read) return the status of the proposal: pending, writing, executed, partial, failed, rejected or expired.

The availabilities:draft scope is offered only to a person who could also approve the change (the rights to manage stock sync and to edit products). An existing key or consent does not inherit it. REST v1 stays read-only. The proposal parameters are in the MCP interface, the approval screen in the Availability guide.

Claims: settings for reading and a proposed change

Section titled “Claims: settings for reading and a proposed change”
  • claims_settings (scope claims:read) returns the processes with IDs and names of types, steps and statuses, and the tags; with the claims-settings:read scope also the module settings.
  • claims_templates and claims_configuration (scope claims-settings:read) return e-mail and document templates (subject, text, when and whether they are sent automatically) and the other settings: tags, fields, return shipping and the shop form, without the integration token.
  • claims_get also carries the case timeline, sent e-mails and tags; message text only with personal-data:read.
  • claims_config_change_draft (MCP only, sensitive scope claims-settings:draft) does not change the settings. It stores a proposed change to processes, statuses, tags and template texts for 72 hours with a preview and approvalUrl; a person allowed to manage the settings writes it with Approve and write under Claims → Settings, in full or not at all. claims_config_draft_get returns its state.

Parameters are in the MCP interface.

Return shipping, product texts and autonomous writing

Section titled “Return shipping, product texts and autonomous writing”
  • claims_routes (scope claims-settings:read, or either claims drafting scope) returns return shipping routes, recipient addresses, carrier profiles with IDs, a return flag and reach, and case type keys. claims_routes_change_draft (MCP only, sensitive scope claims-routes:draft) proposes creating, updating, enabling or disabling a route. The server validates it exactly like the screen: a profile with returns enabled, carrier reach, an existing address and types, a non-negative price and no conflict with an enabled route. Deleting a route over MCP is not possible.
  • products_content_get and GET /products/:code/content?market= (scope product-content:read) return a product’s description, short description and SEO texts straight from the shop, each field with a hash and whether the platform can write it. categories_content_get and GET /categories/:guid/content?market= (scope category-content:read) return the same for a category.
  • products_content_change_draft and categories_content_change_draft (MCP only, sensitive scopes product-content:draft and category-content:draft) propose new texts, up to 30 items at once. They accept content fields only; price, stock, availability, code, EAN or name cannot be changed this way. HTML is validated: no script except one JSON-LD FAQPage block, no on…, javascript: or iframe. On approval the text is compared with the shop’s current state, and if someone changed it in the meantime nothing is written (CHANGED_SINCE_DRAFT). If the shop alters the text when saving, the result says so (MODIFIED_BY_PLATFORM). Proposals are approved under Warehouse → Product changes. On WooCommerce, a draft containing a script (including JSON-LD) or a backslash is blocked (PLATFORM_STRIPS_SCRIPT, PLATFORM_STRIPS_BACKSLASH): WordPress removes them when saving and customers would see the rest as text.
  • products_content_policy and GET /product-content/policy?market= (scope product-content:read) tell you, without calling the shop, what your key may do with texts on a given shop: whether it may read (readEnabled) and propose (draftEnabled, proposals over MCP only), which fields the platform writes (supportedFields; SEO fields on WooCommerce only with an SEO plugin), the approval mode (approvalMode: human, autonomous or disabled) and whether a proposal is written automatically (autonomousWriteEnabled), proposal limits and the hash algorithm (sha256). A paused shop, an unsupported platform or a read-only shop key are a status and reason in the response, not an error. The category field carries the same for categories. The structuredData field tells whether the platform keeps structured data in the product description: on WooCommerce it does not (NOT_SUPPORTED, PLATFORM_STRIPS_SCRIPT; structured data there is managed by the store theme, THEME_MANAGED), on Shoptet it does (one FAQPage block).
  • Autonomous writing. By default every proposal (claims settings and routes, product and category texts) is written only when a person approves it. An administrator can switch it on per area under Settings → API & MCP → Writing via AI. The proposal is then written immediately, the same way as an approval, on behalf of the person who granted the AI access, and only if that person has the right to approve the change right now. Otherwise the proposal waits and the response says why. Every change of the mode is recorded.

Existing keys and consents do not inherit the new scopes; a new consent is needed.

REST and MCP are reading on demand. When your system should learn about an event immediately — a new order, payment, status change, shipment, delivery, stock movement, invoice, claim — it subscribes over outbound webhooks: MitoOps sends a short envelope with identifiers to your endpoint, signed with HMAC-SHA256, with retries on failure and a delivery log. The system then loads the detail over REST.

Subscriptions are created by a person in the app on the same screen as keys; over REST and MCP endpoints are only read (webhooks:read, without the secret). An endpoint can also be used as an automation step. Details in outbound webhooks.

API & MCP and webhooks are part of every paid plan from Start up. Plans differ in the number of active keys and endpoints, not in what can be read:

Plan API & MCP Active access keys Webhook endpoints
Trial — 0 0
Beginner — 0 0
Start yes 1 5
Growth yes 2 20
Pro yes 5 50
Custom yes by agreement by agreement

The server enforces the limits: an attempt to add a key or endpoint above the limit is rejected with an explanation. Replacing a key or rotating an endpoint secret does not use up a slot. Downgrading does not revoke existing keys or endpoints — a new one just cannot be created until the count drops below the new cap. Connecting over OAuth does not consume a key.

Current values for your account including usage (active automations, runs this month, e-mails, credits) are returned by account_entitlements / GET /account/entitlements with the account:read scope. It carries only the plan, features and limits — no billing data. The current price list is at mitoops.com/en/cennik.

Limit Measured on How much
before authentication the address you call from 300 calls / 60 s
after authentication the specific key 600 calls / 60 s

The first prevents key guessing, the second is yours and shared with nobody. Exceeding it is 429 with RateLimit-* headers. It is not a plan quantity — calls are not billed.

An error response always has the same shape and carries a code:

{ "error": { "code": "store_required", "message": "…", "requestId": "…" } }
Status Code When
400 invalid_request a parameter does not match the contract (bad date, reversed period, invalid cursor)
400 store_required a call over shop data without market
401 unauthorized missing, unknown, revoked or invalid key
403 forbidden the key lacks the required scope
403 store_forbidden a shop outside the key’s scope
404 not_found the record does not exist (also when it belongs to another shop)
405 — anything other than GET (REST)
409 conflict the draft write hit another version, a reused clientRequestId or a changed catalogue (MCP)
429 rate_limited technical call limit exceeded

The reason for a 401 is not distinguished — the difference would help whoever is guessing keys. Quote the requestId when reporting a problem to support. Over MCP an error the assistant can recover from arrives as a tool result flagged isError; a protocol error as a JSON-RPC error.

Terminal window
# Orders for a period, paged
curl -H "Authorization: Bearer <your key>" \
"https://<your address>/api/v1/orders?market=en&from=2026-08-01&to=2026-08-31&limit=50"
# Delivery statistics for August
curl -H "Authorization: Bearer <your key>" \
"https://<your address>/api/v1/shipping/stats?market=en&from=2026-08-01&to=2026-08-31"
# Claims statistics for August
curl -H "Authorization: Bearer <your key>" \
"https://<your address>/api/v1/claims/statistics?market=en&from=2026-08-01&to=2026-08-31"
# Plan and account limits with usage
curl -H "Authorization: Bearer <your key>" \
"https://<your address>/api/v1/account/entitlements"

Questions Claude.ai answers from MitoOps data once connected: “What was the median delivery time of DHL and GLS in August?”, “How many orders came from ChatGPT?”, “What is the margin of product X over the last month?” (with purchase-prices:read), “How many claims are overdue?”, “Propose an automation that sends a reminder three days after an unpaid order” (with automations:write — a disabled draft is created), “Rename the Backorder availability on the SK shop to Ships in 5 days” (with availabilities:draft a proposal is created, which you write by approving it in the app).

  • Tenant isolation. The client comes exclusively from the credential; every client has its own database.
  • Shop scope is the intersection of the credential’s list and the shops connected at that moment. On calls over one shop’s data market is required — a missing shop is 400, a shop outside the scope 403.
  • The person’s rights. The consent screen offers only scopes the signed-in person has themselves; the account’s own permission set decides.
  • The limits of every write are enforced by the service, not by an annotation: an automation draft is always created disabled, a published automation is never changed over MCP, and a proposed availability change writes nothing to the shop until a person approves it in the app.
  • Validity and revocation. An OAuth access token lasts an hour, a refresh token 30 days; a revoked consent stops every token derived from it. Keys can be revoked or replaced immediately.
  • Audit. Every call is recorded with the capability name, the interface and a fingerprint of the input — without values.
  • What you cannot rely on: non-public application routes (the interface is /api/v1 and /api/mcp, nothing else), direct database access (does not exist) and credentials (the interface never returns them).