# Migration: v1 → v2

Last updated: 2026-07-31

v1 (/api/v1) remains live. Migration is not required immediately.
v1 responses now include: Deprecation: false, Link: </api/v2>; rel="successor-version"

## What changed

### Base URL
- v1: https://orita.online/api/v1
- v2: https://orita.online/api/v2

### Provider fields renamed
| v1 field    | v2 field           |
|-------------|-------------------|
| name        | displayName        |
| profession  | professionCode     |
| specialty   | specialtyCodes     |
| languages   | languageCodes      |
| modality    | modalityCodes      |
| insurance   | insurancePlanCodes |

### New required v2 fields
- externalId — your stable identifier for each provider
- licenseRecords — array with regionCode, status, expiresAt, verifiedAt
- serviceRegionCodes — regions where provider can serve clients
- ageGroupCodes — supported patient age groups

### Resolution request changes
- service: "therapy" → serviceId: "svc_therapy_initial"
- constraints now use anyOf: { anyOf: ["es"] } instead of string
- licenseRegionCodes is now a hard constraint (was ignored in v1)
- insurancePlanCodes is now a hard constraint with alias normalization

### New v2-only endpoints
- POST /api/v2/provider-imports — bulk upsert
- GET  /api/v2/resolutions/:id/candidates — per-provider explanations
- POST /api/v2/ranking-policies — versioned ranking
- POST /api/v2/organizations — multi-tenant hierarchy
- POST /api/v2/waitlist — zero-result waitlists
- POST /api/v2/continuity — patient-provider relationships
- GET  /api/v2/audit-events — immutable audit log

### Error format
v2 uses a canonical error envelope:
```json
{
  "error": {
    "code": "LICENSE_REGION_MISMATCH",
    "message": "...",
    "status": 422,
    "requestId": "req_...",
    "recoverable": true,
    "suggestedAction": "..."
  }
}
```

All v2 responses include: X-Orita-Request-Id header.

## Migration steps

1. Update base URL to /api/v2
2. Rename provider fields (see table above)
3. Add externalId and licenseRecords to provider data
4. Update resolution constraints to anyOf syntax
5. Replace service: "string" with serviceId: "svc_..."
6. Implement canonical error handling (error.code, error.requestId)
7. Add Idempotency-Key to confirmation requests (required in v2)
8. Test with GET /api/v2/resolutions/:id/candidates to verify eligibility

## Compatibility

v1 and v2 can be used simultaneously. No data migration required.
Existing v1 bookings, professionals, and event types remain accessible.
