system
5 Operationen
Health, readiness, the contract itself, and the identity of the calling principal. None of these carry business data.
Für Entwickler
SIDES LABS ist die API der Plattform, auf der Gastronomiebetriebe ihre Bestellungen, Zahlungen und ihr Backoffice führen. Bauen Sie dagegen, listen Sie das Gebaute im Marktplatz, und SIDES-Kunden installieren es.
curl -X POST https://api.sideslabs.com/v1/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode "username=$CLIENT_ID" \
--data-urlencode "password=$CLIENT_SECRET" \
--data-urlencode 'scope=marketplace.apps'
{ "access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 900,
"scope": "marketplace.apps" }
Die Oberfläche
Das sind die Gruppen und die Zählungen des Vertrags selbst, gelesen aus
GET /v1/publication/public/api-reference — demselben Dokument, gegen das der Server seinen Router beim Start prüft. Diese Seite führt keine eigene Endpunktliste, es gibt hier also nichts, was veralten könnte.
Der Vertrag dokumentiert 388 Operationen, in Version 1.0.0.
5 Operationen
Health, readiness, the contract itself, and the identity of the calling principal. None of these carry business data.
31 Operationen
Both authentication planes. Machine clients exchange configured credentials at /v1/oauth/token (plane 1); partner users register, sign in, rotate and sign out under /v1/auth (plane 2).
The two issue the same kind of access token and are checked by the same middleware, and they identify different things: a client id names a program an operator provisioned, a subject names a person. A partner user's scopes are derived from their role and their tier and are never requested; a machine client may down-scope its own token, because it is a program with a purpose.
25 Operationen
Everything SIDES publishes to partner developers: the API changelog, the developer blog, and the developer-resources area with the API reference and its downloadable artefacts.
The changelog is part of the API contract, not marketing. Every release writes an entry through this API, which is what keeps our own release notes and the public changelog one thing rather than two that drift.
Nothing here reaches a reader without an explicit, recorded transition under labs.admin.publication:write — one editorial capability over all three, not three. Developer resources carry a second, orthogonal question besides: audience decides whether a released resource is for the open internet or for authenticated partners, and the anonymous surfaces gate on both.
26 Operationen
Partner tiers and what they grant: the public catalogue the pricing page and the registration form render, and the resolved entitlements of one business partner.
A tier is data, not code — a new tier is a row set — and the subscription row, never the payment provider, is what decides access.
81 Operationen
The marketplace: the apps a partner offers with their version history, and the category tree those apps are sorted into.
Categories are SIDES-internal to write and public to read — two access classes over one set of rows, and a third in between: an internal READ that sees the deactivated categories the public endpoint never returns. A partner chooses a category and cannot invent one, which is a fact about the scope tree rather than a check in a handler: every category write sits under labs.admin, and a principal bound to a business partner can never reach that subtree.
Apps are the other way round: partner-scoped throughout, under marketplace.apps. The partner appears in no path and in no body — it comes from the token — so a request naming somebody else's app is not refused, it is unrepresentable.
The storefront is here, and it is a different set of paths. Everything under /v1/marketplace/public/ — the catalogue, one listing, its media and the category tree — carries the storefront scope rather than an owner's, and shows only what an explicit, recorded transition has put there. Everything else in this tag answers for one owner. The two never share a shape.
45 Operationen
A business partner's own record: its team, the invitations it has sent, and later its profile and imagery.
Every path here carries the partner's uuid, and every one of them COMPARES it against the token rather than selecting by it. The business partner a query sees comes from the authenticated principal; a uuid naming somebody else is 403, which is what makes reaching into another partner's team unrepresentable rather than merely forbidden.
6 Operationen
How many SIDES customers use a partner's apps, and the state of the import that answers that question.
The numbers are a CACHE with a ledger beside it, and the ledger is what makes the cache honest. Platform usage is read through the SIDES API and never by querying the platform's own schema, so what SIDES LABS holds is a rollup of what that API last said. Every endpoint here therefore answers when it last said it: GET /v1/statistics/import-status is that answer on its own, and the partner-facing reads carry the same freshness from the same computation.
Which SIDES API, at which granularity, and whether it is pulled or pushed is an OPEN question. The assumption in force is a scheduled pull of completed days into a rollup, and the default configuration imports nothing at all and says so — source: DISABLED — because a platform with no statistics is supportable and one with invented statistics is not.
Both endpoints in this tag are SIDES-internal. They are about the JOB; a partner's own numbers are a different access class over the same rows.
125 Operationen
SIDES-internal administration across every partner: the business partners themselves, and the platform overview an administrator opens on.
Everything in this tag is a cross-partner read or write, and every operation in it is audited — reads included. That is what the tag IS: each operation writes one audit_log record, in the same transaction as the answer, and an answer whose record cannot be written is refused rather than given untraced.
/v1/admin/… is not /v1/partner/… with a wider filter. Every path in the partner tag carries a partner uuid and COMPARES it against the token; nothing there can name a partner the caller is not. The uuid in these paths ADDRESSES any partner on the platform. They are two collections for two audiences, and no query parameter widens one into the other — a single endpoint serving both is a shape this platform does not build.
The other SIDES-internal surfaces are not in this tag and that is deliberate: tier administration, category maintenance, app approval, review moderation and the support desk each live beside the partner-facing operations over the same rows, where a reader compares the two. What is here is what has no partner-facing twin.
44 Operationen
The community surfaces: the feature-request board partners propose on and vote on, and the comments under it.
The board is read across every partner, and that is its design rather than a leak. A board on which each company saw only its own wishes cannot be voted on, and voting is the feature. What makes it safe is the shape of the answer, not a filter: every entry names the proposing COMPANY and names the person only on that person's own opt-in, and no endpoint here says who voted — only how many did, and whether the caller is one of them.
Nothing on this board is public. Every path requires a token and there is no …/public/… route in this tag. A state called SHIPPED is SIDES answering a partner, not a publication state.
Two access classes: a partner proposes, votes and comments under engagement.feature-requests; SIDES changes a status, merges duplicates, pins, suspends and moderates under labs.admin.engagement. The second is inside the SIDES-internal tree, which is what makes "a partner cannot change a status" a fact about the authorization model rather than a check in a handler.
A proposal is not moderated on the way in and can be taken off the board afterwards. Its title and body reach every other partner the moment it is written, deliberately — and :suspend is the way back, the only operation here that removes a partner's words.
Die vollständige Referenz steht im Partnerportal. Jede Operation mit ihren Parametern, ihren Antworten und dem Scope, den sie verlangt, steht in der API-Referenz, und das OpenAPI-Dokument selbst ebenso. Die Registrierung öffnet beides, und sie ist ein Schritt: Sie legt Ihren Geschäftspartner, Ihren ersten Administrator und Ihr Abonnement zusammen an.
Anmeldung
Ein Maschinenclient und ein Partnernutzer melden sich unterschiedlich an und landen bei derselben Art Zugriffstoken, geprüft von derselben Middleware. Welche Sie brauchen, hängt davon ab, ob ein Mensch anwesend ist.
Ein Server-zu-Server-Verbraucher — Ihre CI, die Changelog-Einträge einliefert, Ihr Backend, das eine App-Version abgleicht. Die Zugangsdaten sind eine Client-Kennung und ein Geheimnis, das SIDES ausgibt; es gibt keine Person und kein Erneuerungs-Cookie.
grant_type=password
username=$CLIENT_ID
password=$CLIENT_SECRET
scope=publication.changelog:write
Die angeforderte Berechtigung wird mit dem geschnitten, was der Client darf. Mehr anzufordern ist kein Fehler und bringt Ihnen nicht mehr.
Ein Mensch, der sich am Partnerportal anmeldet. Die Antwort trägt ein kurzlebiges Zugriffstoken und setzt ein Erneuerungs-Cookie, das
HttpOnly; Secure; SameSite=Strict ist — das einzige Zugangsmittel, das ein Neuladen der Seite überlebt, und es wird bei jeder Verwendung erneuert.
{ "email": "[email protected]",
"password": "…" }
200 { "access_token": "eyJhbGciOi...",
"expires_in": 900 }
Set-Cookie: __Host-refresh=…; HttpOnly; Secure; SameSite=Strict
Zweiter Faktor aktiv? Der erste Aufruf antwortet MFA_REQUIRED und der Code geht an /v1/auth/sessions:verify-mfa. Das ist absichtlich eine eigene Anfrage: zwei Aufrufe, zwei Budgets, zwei Protokollzeilen.
Welche Ebene es auch ausgegeben hat — das Token gehört in die
Authorization -Kopfzeile und nirgendwo sonst. Nie in einen Abfrageparameter — eine URL erreicht das Zugriffsprotokoll, den Browserverlauf und die Referrer-Kopfzeile.
curl https://api.sideslabs.com/v1/system/me \
-H "Authorization: Bearer $ACCESS_TOKEN"
{ "principal_type": "PARTNER_USER",
"scopes": ["partner:write", "marketplace.apps:write", …],
"rate_limit": { "limit_per_second": 10, "remaining_day": 49873 } }
/v1/system/me ist der Endpunkt, den man zuerst aufruft, wenn etwas antwortet mit 403: Er sagt Ihnen, welche Berechtigungen das Token tatsächlich trägt, und das ist meist die ganze Antwort.
Berechtigungen
marketplace → marketplace.apps →
marketplace.apps:write. Eine übergeordnete gewährt ihre untergeordneten, ein Token mit der übergeordneten erreicht also alles darunter.
:write schließt Lesen ein:write ist nur lesend, und wer die Schreibberechtigung hält, muss die Leseberechtigung nicht zusätzlich anfordern.
marketplace gewährt
marketplace.apps — und nicht
marketplace.apps:write. Eine übergeordnete gewährt ihre untergeordneten
auf ihrer eigenen Zugriffsstufe, nie darüber.
Ressourcen
Dargestellt aus GET /v1/publication/public/developer-resources. Alles hier ist öffentlich. Hinter einer Partneranmeldung gibt es mehr — die Ressourcen, deren Zielgruppe partner ist, werden nicht aus dieser Liste gefiltert, sie standen nie darin.
Bisher wurde keine öffentliche Anleitung und keine Sammlung veröffentlicht. Partnerinternes Material kann es geben — das liegt hinter der Partneranmeldung und zählt hier nicht mit.
Fragen
Nein. Der Vertrag ist das Produkt: Die Referenz, diese Seite, das Changelog und der Blog brauchen überhaupt kein Token, und das OpenAPI-Dokument wird als YAML ausgeliefert. Eine Partnerschaft brauchen Sie für Zugangsdaten und um Software im Marktplatz zu listen — nicht, um zu beurteilen, ob die API tut, was Sie brauchen.
Ein Feld, einen Endpunkt oder einen Aufzählungswert zu ergänzen ist keine brechende Änderung, und von Ihrem Client wird erwartet, dass er ignoriert, was er nicht kennt. Eines zu entfernen, umzubenennen oder umzutypisieren braucht eine neue Hauptversion und mindestens sechs Monate Vorlauf, mit dem Abschaltdatum im Changelog und in der
X-SIDES-Deprecation -Kopfzeile jeder betroffenen Antwort.
Zwei Budgets, nicht eines: eine Stoßgrenze pro Sekunde und ein Tagesbudget, beide vom Partnertarif gesetzt. Jede Antwort trägt X-RateLimit-*, und ein Überschreiten antwortet 429 RATE_LIMITED mit einem Retry-After , dem Sie folgen sollten, statt zu raten. Die Tarife sagen, was jede Stufe erlaubt.
Noch nicht, und diese Seite tut nicht so. Es gibt heute ein Partnerkonto im kostenfreien Tarif gegen die Live-API, mit Ihren eigenen Daten — genug, um eine Anbindung zu bauen, nicht genug, um sie unter Last zu prüfen. Fragen Sie den Support, bevor Sie eine Testsuite darauf richten.
Jede, und keines. Die API ist REST über HTTP mit JSON-Rümpfen und OAuth-2.0-Bearer-Token — es gibt kein SDK, das Sie übernehmen müssten, und keine Clientbibliothek, die mitgeführt werden muss. Die Postman- und Insomnia-Sammlungen oben werden aus demselben Vertrag erzeugt, den der Server durchsetzt.
Die Registrierung legt Ihren Geschäftspartner, Ihren ersten Administrator und Ihr Abonnement in einem Schritt an. Der kostenfreie Tarif reicht, um dagegen zu bauen.