Authentication and API keys
The API uses company API keys (service accounts, not tied to a user). Every request is authenticated with the key as a Bearer token:
curl https://api.kinmu.app/v1/organization \
-H "Authorization: Bearer kinmu_sk_live_xxxxxxxx"Nature of the keys
The company is always resolved from the key: you never send a companyId in the URL or the body.
| Aspect | Detail |
|---|---|
| Format | kinmu_sk_live_<40+ chars> (production) · kinmu_sk_test_<40+ chars> (sandbox). |
| Visibility | Shown only once when created. Afterwards you only see the prefix + the first few characters. |
| Issuance | From the dashboard my.kinmu.app → Developers (only global_admin / company_manager). |
| Limit | Maximum 10 active keys per company. |
| Expiration | Optional (90 / 180 / 365 days or no expiration). |
Scopes
Each key carries explicit scopes (least privilege). Without the required scope, the endpoint responds 403 invalid_scope.
| Scope | Allows |
|---|---|
org:empleados:read | Read employees. |
org:empleados:write | Add, update and offboard employees. |
org:fichajes:read | Read check-ins and work summaries. |
org:fichajes:write | Record check-ins. |
org:ausencias:read | Read absences. |
org:ausencias:write | Create, approve and reject absences. |
org:saldos:read | Read vacation balances. |
org:estructura:read | Read locations and units. |
org:informes:read | Request and download reports. |
webhooks:manage | Manage outbound webhooks. |
GET /v1/organization does not require a specific scope: it is used for introspection and to validate the key. Reports additionally require the read scope of their domain: e.g. absences_export requires org:ausencias:read.
Grant each integration only the scopes it needs.
Sandbox
kinmu_sk_test_ keys always operate against a sandbox company with synthetic data, isolated from your real data. See the Sandbox guide.
Rotation
Rotating a key = create a new one and revoke the old one. Zero-downtime flow:
- Create the new key with the same scopes.
- Deploy your integration with the new key.
- Verify that it works (for example, a
GET /v1/organization). - Revoke the old key.
Revocation
Revocation is immediate from the dashboard: the key stops working on the next request (401 unauthenticated). Immediately revoke any key you suspect is compromised and review its last_used_ip.
Best practices
- Never publish a key in client code, mobile apps, repositories or logs. They are server credentials.
- Store them in a secrets manager or environment variables.
- Use one key per integration so you can revoke granularly.
- Apply least privilege: only the essential scopes.
- Set an expiration and rotate periodically.
- In logs, never record the
Authorizationheader.
Authentication errors
| HTTP | code | Cause |
|---|---|---|
| 401 | unauthenticated | Missing key, or the key is invalid, revoked or expired. |
| 403 | invalid_scope | The key lacks the required scope (errors.required_scope). |
| 403 | subscription_inactive | The company’s subscription is suspended. |
| 403 | addon_disabled | The Public API addon is not active. |
See the full error format in Conventions → Errors.