Public API (v1)
| Field | Value |
|---|---|
| Status | Deferred. Not included in any current tier. |
| Owner | Unassigned |
| Target repos | attunelogic-api, attunelogic-service |
| Related | Monetization & Tier Packaging (v1), Outbound Webhooks (v1), Feature Roadmap Index |
| Last updated | 2026-04-23 |
Status banner: Full public API (read + write) was removed from the public Pro roadmap in v1. The current API surface is used internally by the service web and mobile apps; it is not a contract we publish or version for third parties.
Why this was removed from v1
- No API-token model exists. Today, all endpoints authenticate via the first-party user session. Opening the same endpoints to third-party tokens without scopes, per-token rate limits, and a revocation UI would be a multi-tenant safety risk.
- No versioning strategy exists for our internal API. Publishing it as-is would lock us into shape decisions we're not ready to commit to.
- Customers who need programmatic access in the short term can use the planned outbound webhooks for push and the upcoming iCal / CSV exports for pull.
What shipping this requires
Data model
- New
ApiTokenmodel scoped byparentCompany:name: string(human-readable label: "Zapier prod")prefix: string(first 8 chars, shown in the list UI:al_live_abcdef12…)hash: string(SHA-256 of the full secret; full secret shown once at creation, never again)scopes: string[](e.g.read:jobs,write:invoices, …)lastUsedAt: DateexpiresAt: Date(optional; default never)ipAllowlist: string[](optional)createdBy,revokedAt,revokedBy
Scope system
Scope strings in the form <action>:<resource>:
read:jobs,write:jobsread:invoices,write:invoicesread:clients,write:clientsread:drivers,write:driversread:reports
Phase 1 ships read-only scopes for jobs, invoices, clients, drivers, reports. Phase 2 ships write scopes behind an explicit per-tenant opt-in.
Authentication middleware
- Bearer token:
Authorization: Bearer al_live_… - Middleware pulls the token, hashes, looks up the
ApiToken, attachesreq.tenantandreq.tokenScopes. - Route handlers call a thin helper:
requireScope("read:jobs")that checksreq.tokenScopes. - Sessions and tokens are mutually exclusive; no shared auth surface.
API surface changes
- New versioned prefix:
/api/public/v1/...(separate from the existing internal/api/v1/...). - Route-level rate limits via the existing
src/services/rateLimiting.jsplus per-token quotas (e.g. 10 req/s, 1,000 req/min, 100k req/day). - OpenAPI 3.1 spec generated from route handlers; served at
/api/public/v1/openapi.json.
Service web UI
Settings → Developers → API tokens:- Create token → scope picker, expiry picker, IP allowlist — reveal-once modal with the full secret.
- Token list with prefix, scopes, last-used, revoke button.
- Live usage charts (req/min, 4xx / 5xx breakdown).
Security
- Enforce
parentCompanyscoping on every query — no token-scoped query may read across tenants, period. - Log every API call with token id, scope used, response code, response time — fuels the usage UI and supports incident response.
- Refuse tokens without TLS. Refuse tokens from IPs outside the allowlist if configured.
- Rotation: tokens can be "soft-rotated" — admins mint a replacement, both work for 7 days, then old one auto-revokes.
Tests
- Unit: scope parsing, rate limit bucket accounting, hash-on-create / compare-on-lookup.
- Integration: token lifecycle, scoped access denied, revocation, expired-token rejection.
- Tenant isolation: token from tenant A cannot reach tenant B's resources through any public route.
Docs
- Hosted API reference at
docs.attunelogic.com/api/public/v1/.... - Getting started guide (curl + Postman collection).
- Rate-limit policy page.
Dependencies on existing infra
- Rate limiting —
src/services/rateLimiting.jsalready wraps Redis-backed limits; reuse the same infra with per-token keys. - AuditLog — token create / revoke are natural audit events.
- Feature flag registry —
api.public.enabledis already reserved as a future flag. - Outbound webhooks (v1) — shared developer-settings IA; ship the two in the same quarter.
Estimated timeline and risk
- Effort: 3–4 weeks for read-only (Phase 1). Additional 2–3 weeks for write scopes (Phase 2).
- Risk: High. Publishing a public API is a forever-contract. Budget time for deliberate shape review before Phase 1 goes live. Once we ship
GET /api/public/v1/jobs, we own that shape for years.
Open questions
- Do we version per-endpoint (
/v1path) or header-versioned (Attunelogic-Version: 2026-04-23) like Stripe? - Do we offer SDKs in Node and Python at launch, or start with curl + Postman only?
- Do we allow customer-scoped tokens (single-driver access) or only tenant-scoped?
Cross-references
- Rate limiting:
attunelogic-api/src/services/rateLimiting.js - Outbound webhooks: Outbound Webhooks (v1)
- Billing proposal: Monetization & Tier Packaging (v1)
- Roadmap index: Feature Roadmap Index