TattooBookingDevelopers

Changelog

Every public API change, in chronological order. Subscribe to email updates by adding developers@tattoobooking.com to your address book (real subscription feed coming in Phase 7).

2026-09-11 — Shop consultation desks are consult-only

Changed

  • POST /v1/appointments now refuses an event_type_id that belongs to a different artist than artist_id — 400 problem-json with code validation_error. Previously the mismatch was accepted and the appointment landed on the wrong calendar.
  • New error code. A shop's consultation desk (an artist record that exists only to host the shop's consultations) accepts consultation event types only. Booking anything else on it returns 422 problem-json with code desk_consult_only. Regular artists are unaffected.

2026-09-09 — Appointment writes are validated against availability

Changed

  • PATCH /v1/appointments/:id and POST /v1/appointments now check the requested time against the artist's availability — the same rules the public booking page applies: an overlap with another appointment, a time outside working hours, a reached daily cap, a time block or a Google Calendar busy event is refused. Previously an update moved an appointment anywhere, including on top of another booking.
  • New error code. A refused time returns 409 problem-json with code slot_unavailable, a detail sentence and a failures array of { code, message } pairs in plain words (for example appointment_conflict, outside_working_hours, max_appointments_per_day, google_calendar_busy). There is no override flag — pick a different time. Unchanged times are not re-validated, so posting an appointment's current times back is still a no-op 200.
  • Appointments recorded without an event_type_id have no schedule to judge hours against, so only the double-booking check applies to them.

2026-09-08 — Reschedules through the API now notify the client

Changed

  • PATCH /v1/appointments/:id emails the client when it moves an appointment. When start_at / end_at actually change the time of a live appointment, the client receives the same reschedule email a dashboard reschedule sends: the old and new times in the appointment's timezone, plus an updated calendar file that replaces the entry they already hold. Nothing is sent for unchanged times, metadata-only edits, a cancelling status in the same request, completed appointments, or clients marked blocked / do-not-contact. Previously an API-driven reschedule updated the record, the artist's Google Calendar and reminders but never told the client.
  • Additive response field. The PATCH response now includes client_notified (true / false) reporting whether that email was sent. object and data are unchanged.

2026-05-27 — Developer platform launch

Added

  • OAuth 2.0 authorization server. Full RFC 6749 + 7636 (PKCE) + 7009 + 7662 + 8414 compliance. Endpoints at /oauth/authorize,/oauth/token, /oauth/revoke, /oauth/introspect,/.well-known/oauth-authorization-server.
  • Outbound webhooks. 32 public event types, HMAC-SHA256 signing with rotation, exponential retry over 72h, auto-pause on 50 consecutive failures. Full CRUD at /v1/webhook_endpoints.
  • /v1/ideas — tattoo idea CRUD. Full TattooIdea field coverage (30+ properties). Filter by client, assigned artist, stage, source type, BTT status, archived status.
  • /v1/event_types — read-only. 40+ EventType fields including public booking URL.
  • /v1/zapier/* — REST Hooks shim. Powers the official Zapier app (5 triggers + 3 actions + 1 search in v1).
  • Expanded DTOs. Form (+4 fields), FormSubmission (+8), Appointment (+4 + event_type_id properly prefixed), Lead (+2). Every DTO now exposes the full set of non-secret fields from the underlying Prisma model.

Plan-gated

  • API access, outbound webhooks, and Zapier integration are unlocked at the Solo plan ($49/mo). The Light (free) tier is locked out.
  • Custom OAuth app registration is unlocked at Studio.

Security

  • Google Calendar OAuth tokens encrypted at rest (AES-256-GCM). Rolling migration in progress — reads flip to encrypted on 2026-06-03, plaintext columns dropped on 2026-06-10.
  • Twilio inbound webhook receiver wired with proper signature verification (was silently broken).

2026-04-15 — Public API foundation

  • Initial /v1/* surface: clients, appointments, leads, forms, submissions, artists, shops, events, webhook_endpoints (stubs), me.
  • RFC 9457 problem+json error responses, cursor pagination, prefixed IDs.
  • API key auth with scopes (25 canonical scopes), IP allowlist, rotation, audit log.
  • Redis-backed tiered rate limiting (free / standard / pro / custom).
  • Postgres-backed idempotency keys (24h window).