Skip to main content

Public API (v1)

FieldValue
StatusDeferred. Not included in any current tier.
OwnerUnassigned
Target reposattunelogic-api, attunelogic-service
RelatedMonetization & Tier Packaging (v1), Outbound Webhooks (v1), Feature Roadmap Index
Last updated2026-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 ApiToken model scoped by parentCompany:
    • 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: Date
    • expiresAt: Date (optional; default never)
    • ipAllowlist: string[] (optional)
    • createdBy, revokedAt, revokedBy

Scope system

Scope strings in the form <action>:<resource>:

  • read:jobs, write:jobs
  • read:invoices, write:invoices
  • read:clients, write:clients
  • read:drivers, write:drivers
  • read: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, attaches req.tenant and req.tokenScopes.
  • Route handlers call a thin helper: requireScope("read:jobs") that checks req.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.js plus 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 parentCompany scoping 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 limitingsrc/services/rateLimiting.js already wraps Redis-backed limits; reuse the same infra with per-token keys.
  • AuditLog — token create / revoke are natural audit events.
  • Feature flag registryapi.public.enabled is 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 (/v1 path) 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