Organisaties & Workspaces
Overzicht
qr3.app gebruikt een hiërarchie met twee niveaus:
Organization (Firma/Agentur) └── Workspace 1 (Kunde A) └── Workspace 2 (Kunde B) └── Workspace 3 (Internes Team)- Organisatie — het hoogste niveau, gekoppeld aan een Stripe-account en abonnement
- Workspace — geïsoleerde omgeving voor QR-codes, scans en API-keys
Organisaties API
GET /v1/organizations
Retourneert de organisatie waartoe de huidige API-key behoort.
curl https://qr3.app/v1/organizations \ -H "Authorization: Bearer qr3_sk_..."GET /v1/organizations/usage
Retourneert het live verbruik van de organisatie ten opzichte van de abonnementslimieten — opgeteld over alle workspaces en live berekend: scans voor de huidige factureringsmaand (ten opzichte van max_scans_per_month) en dynamic_codes, het aantal actieve dynamische codes (ten opzichte van max_dynamic_codes). Beide worden nooit geblokkeerd bij het bereiken van de limiet; gebruik dit eindpunt voor verbruiksweergaven en upgrade-meldingen.
curl https://qr3.app/v1/organizations/usage \ -H "Authorization: Bearer qr3_sk_..."{ "data": { "scans": { "used": 4120, "limit": 5000, "usage_pct": 82, "remaining": 880, "period": "2026-06", "period_start": "2026-06-01T00:00:00.000Z" }, "dynamic_codes": { "used": 142, "limit": 500, "usage_pct": 28, "remaining": 358 } }}POST /v1/organizations
Maakt een nieuwe organisatie aan.
curl -X POST https://qr3.app/v1/organizations \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Digital Heroes GmbH", "slug": "digital-heroes", "billing_email": "[email protected]" }'Velden:
| Veld | Type | Verplicht | Omschrijving |
|---|---|---|---|
name | string | ✅ | Weergavenaam (max. 255 tekens) |
slug | string | ✅ | URL-vriendelijk, uniek (min. 2, max. 63 tekens, alleen a-z0-9-) |
billing_email | string | — | Facturatie-e-mailadres |
PATCH /v1/organizations/:id
Wijzigt de naam, het factuur-e-mailadres en het notificatie-e-mailadres van de organisatie.
Alleen een org_admin kan ze wijzigen, in een dashboard-sessie. Verzoeken met een API-key worden geweigerd met 403 — ook qr3_sk_- en qr3_test_sk_-keys —, dus een gelekte key kan het factuur- of notificatieadres niet omleiden.
DELETE /v1/organizations/:id
Soft-delete van de organisatie. Alle bijbehorende workspaces en QR-codes blijven behouden, maar zijn niet langer toegankelijk.
Vereist de rol org_admin (dashboard-sessie). Verzoeken met een pure API-key worden geweigerd met 403 — API-keys krijgen nooit een admin-rol, dus een gelekte key kan de organisatie niet verwijderen.
Workspaces API
GET /v1/workspaces
Lijst van de workspaces die de aanroeper mag zien: org_admin en de eigenaar van de organisatie zien alle workspaces van de organisatie, andere leden alleen de workspaces waar ze bij horen en een API-key alleen de eigen workspace. Een workspace die de aanroeper niet ziet, antwoordt op elke route /v1/workspaces/:id met 404, precies zoals een onbekende ID.
curl https://qr3.app/v1/workspaces \ -H "Authorization: Bearer qr3_sk_..."POST /v1/workspaces
Nieuwe workspace aanmaken.
curl -X POST https://qr3.app/v1/workspaces \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Kunde Bäckerei Schmidt", "slug": "baeckerei-schmidt", "default_locale": "de", "primary_color": "#8B4513", "approval_required": false }'Met een API-key mag alleen een key een workspace aanmaken die door een org_admin of de eigenaar van de organisatie is aangemaakt; elke andere key krijgt 403, nog vóór de controle van de slug (het antwoord verraadt dus niet welke slugs bezet zijn). De rol van wie de key heeft aangemaakt wordt bij elk verzoek gecontroleerd: wordt die persoon gedegradeerd, dan verliest de key dit recht. Een API-key is gebonden aan de eigen workspace en ziet de nieuwe daarna niet: de id ervan staat in het 201-antwoord; een org_admin opent hem in het dashboard en kan daar een key ervoor aanmaken. In het dashboard mag alleen een org_admin workspaces aanmaken.
Velden:
| Veld | Type | Standaard | Omschrijving |
|---|---|---|---|
name | string | — | Weergavenaam (verplicht) |
slug | string | — | URL-vriendelijk, uniek per organisatie (verplicht) |
default_locale | string | de | Standaardtaal |
approval_required | boolean | false | Gereserveerd voor de geplande goedkeuringsworkflow (niet geïmplementeerd) |
primary_color | string | — | Merkkleur (#RRGGBB) |
Abonnementslimieten:
| Abonnement | Max. workspaces |
|---|---|
| Free | 1 |
| Pro | 1 |
| Business | 10 |
| Agency | 50 |
| Enterprise | 500 |
PATCH /v1/workspaces/:id
curl -X PATCH https://qr3.app/v1/workspaces/ws_xyz789 \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Neuer Name", "approval_required": true }'DELETE /v1/workspaces/:id
Archiveert de workspace. Kan niet worden toegepast op de eigen workspace.
Vereist org_admin of ws_admin van de te archiveren workspace; andere rollen krijgen 403. Een workspace die de aanroeper niet ziet, antwoordt met 404 — voor een API-key is dat elke workspace behalve de eigen, die hij evenmin kan archiveren.
Audit-logs
GET /v1/audit-logs
Traceerbaar logboek van alle wijzigingen in de workspace.
curl "https://qr3.app/v1/audit-logs?resource_type=codes&limit=50" \ -H "Authorization: Bearer qr3_sk_..."Query-parameters:
| Parameter | Type | Omschrijving |
|---|---|---|
resource_type | string | Filteren op bron: codes, api_keys, webhooks, workspaces |
resource_id | string | Filteren op specifieke bron-ID |
action | string | Filteren op actie (bijv. codes.created) |
cursor | string | Paginering-cursor |
limit | integer | Max. 100 (standaard: 50) |
Voorbeeldrespons:
{ "data": [ { "id": "aud_a1b2c3", "actor_type": "api", "action": "codes.created", "resource_type": "codes", "resource_id": "qr_xyz123", "changes": {}, "created_at": "2026-03-15T10:00:00.000Z" } ]}