{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"AppController_getHello","parameters":[],"responses":{"200":{"description":""}},"summary":"Service landing page","tags":["Service"]}},"/identities":{"post":{"description":"Idempotency-Key is optional. Missing key still creates. Replay of the same key returns the stored identity (200).","operationId":"IdentityController_create","parameters":[{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"idempotency-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"S2S replay key. Same key returns the same identity.","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIdentityDto"}}}},"responses":{"200":{"description":"Stored identity replayed for this Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityResponseDto"}}}},"201":{"description":"Identity created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityResponseDto"}}}},"400":{"description":"Invalid input data"}},"summary":"Create a new identity","tags":["Identities"]},"get":{"operationId":"IdentityController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort by","schema":{"default":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"DESC","type":"string","enum":["ASC","DESC"]}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"List of identities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}}},"summary":"Get all identities with pagination","tags":["Identities"]}},"/identities/{id}":{"get":{"operationId":"IdentityController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Identity ID","schema":{"format":"uuid","type":"string"}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"Identity found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityResponseDto"}}}},"404":{"description":"Identity not found"}},"summary":"Get identity by ID","tags":["Identities"]},"put":{"operationId":"IdentityController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Identity ID","schema":{"format":"uuid","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIdentityDto"}}}},"responses":{"200":{"description":"Identity updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityResponseDto"}}}},"404":{"description":"Identity not found"}},"summary":"Update identity","tags":["Identities"]}},"/auth-links":{"post":{"operationId":"AuthLinkController_create","parameters":[{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAuthLinkDto"}}}},"responses":{"201":{"description":"AuthLink created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthLinkResponseDto"}}}},"400":{"description":"Invalid input data"}},"summary":"Create a new authLink","tags":["AuthLinks"]},"get":{"operationId":"AuthLinkController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort by","schema":{"default":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"DESC","type":"string","enum":["ASC","DESC"]}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"List of authLinks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}}},"summary":"Get all authLinks with pagination","tags":["AuthLinks"]}},"/auth-links/{id}":{"get":{"operationId":"AuthLinkController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"AuthLink ID","schema":{"format":"uuid","type":"string"}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"AuthLink found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthLinkResponseDto"}}}},"404":{"description":"AuthLink not found"}},"summary":"Get authLink by ID","tags":["AuthLinks"]},"put":{"operationId":"AuthLinkController_update","parameters":[{"name":"id","required":true,"in":"path","description":"AuthLink ID","schema":{"format":"uuid","type":"string"}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAuthLinkDto"}}}},"responses":{"200":{"description":"AuthLink updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthLinkResponseDto"}}}},"404":{"description":"AuthLink not found"}},"summary":"Update authLink","tags":["AuthLinks"]}},"/sessions/me":{"get":{"operationId":"SessionController_me","parameters":[{"name":"authorization","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponseDto"}}}},"401":{"description":"Missing or rejected ZITADEL token"},"403":{"description":"Machine / S2S token cannot JIT a patient"}},"security":[{"bearer":[]}],"summary":"Resolve the caller's MyDermaLife IdentityId from a ZITADEL user token","tags":["Sessions"]}},"/command-inboxes":{"post":{"operationId":"CommandInboxController_create","parameters":[{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommandInboxDto"}}}},"responses":{"201":{"description":"CommandInbox created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandInboxResponseDto"}}}},"400":{"description":"Invalid input data"}},"summary":"Create a new commandInbox","tags":["CommandInboxes"]},"get":{"operationId":"CommandInboxController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort by","schema":{"default":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"DESC","type":"string","enum":["ASC","DESC"]}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"List of commandInboxes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponseDto"}}}}},"summary":"Get all commandInboxes with pagination","tags":["CommandInboxes"]}},"/command-inboxes/{id}":{"get":{"operationId":"CommandInboxController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"CommandInbox ID","schema":{"format":"uuid","type":"string"}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"CommandInbox found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandInboxResponseDto"}}}},"404":{"description":"CommandInbox not found"}},"summary":"Get commandInbox by ID","tags":["CommandInboxes"]},"put":{"operationId":"CommandInboxController_update","parameters":[{"name":"id","required":true,"in":"path","description":"CommandInbox ID","schema":{"format":"uuid","type":"string"}},{"name":"x-internal-api-key","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommandInboxDto"}}}},"responses":{"200":{"description":"CommandInbox updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandInboxResponseDto"}}}},"404":{"description":"CommandInbox not found"}},"summary":"Update commandInbox","tags":["CommandInboxes"]}},"/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Basic health check","tags":["Health"]}},"/health/ready":{"get":{"operationId":"HealthController_readiness","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Readiness check - is the service ready to receive traffic?","tags":["Health"]}},"/health/live":{"get":{"operationId":"HealthController_liveness","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Liveness check - is the service alive?","tags":["Health"]}}},"info":{"title":"Identity API","description":"Stable IdentityId, ZITADEL session resolve, and auth-link binding. IdentityId is not the IdP sub. Owns: Identities, AuthLinks, Sessions.","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://identity.stormbyva.com"}],"components":{"securitySchemes":{"x-internal-api-key":{"type":"apiKey","in":"header","name":"x-internal-api-key","description":"Service-to-service key"}},"schemas":{"CreateIdentityDto":{"type":"object","properties":{"displayName":{"type":"string","description":"The display name of the entity","example":"John Doe"},"primaryMarket":{"type":"string","description":"The primary market of the entity","example":"Sample text"}},"required":["displayName","primaryMarket"]},"IdentityResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier","format":"uuid"},"displayName":{"type":"string","description":"The display name of the entity","example":"John Doe"},"status":{"type":"string","description":"The status of the entity"},"primaryMarket":{"type":"string","description":"The primary market of the entity","example":"Sample text"},"isActive":{"type":"boolean","description":"Whether the record is active"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["id","displayName","status","primaryMarket","isActive","createdAt","updatedAt"]},"PaginationMeta":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Number of items per page"},"totalPages":{"type":"number","description":"Total number of pages"},"hasNextPage":{"type":"boolean","description":"Whether there is a next page"},"hasPreviousPage":{"type":"boolean","description":"Whether there is a previous page"}},"required":["total","page","limit","totalPages","hasNextPage","hasPreviousPage"]},"PaginatedResponseDto":{"type":"object","properties":{"items":{"description":"Array of items","type":"array","items":{"type":"array"}},"meta":{"description":"Pagination metadata","allOf":[{"$ref":"#/components/schemas/PaginationMeta"}]}},"required":["items","meta"]},"UpdateIdentityDto":{"type":"object","properties":{"displayName":{"type":"string","description":"The display name of the entity","example":"John Doe"},"primaryMarket":{"type":"string","description":"The primary market of the entity","example":"Sample text"},"isActive":{"type":"boolean","description":"Whether the record is active"}}},"AuthLinkIdentityRefDto":{"type":"object","properties":{"id":{"type":"string","description":"Identity id","format":"uuid"}},"required":["id"]},"CreateAuthLinkDto":{"type":"object","properties":{"identity":{"description":"The identity of the entity","allOf":[{"$ref":"#/components/schemas/AuthLinkIdentityRefDto"}]},"issuer":{"type":"string","description":"The issuer of the entity","example":"Sample text"},"subject":{"type":"string","description":"The subject of the entity","example":"Sample text"}},"required":["identity","issuer","subject"]},"IdentityEntity":{"type":"object","properties":{}},"AuthLinkResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier","format":"uuid"},"identity":{"description":"The identity of the entity","allOf":[{"$ref":"#/components/schemas/IdentityEntity"}]},"issuer":{"type":"string","description":"The issuer of the entity","example":"Sample text"},"subject":{"type":"string","description":"The subject of the entity","example":"Sample text"},"isActive":{"type":"boolean","description":"Whether the record is active"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["id","identity","issuer","subject","isActive","createdAt","updatedAt"]},"UpdateAuthLinkDto":{"type":"object","properties":{"identity":{"description":"The identity of the entity","allOf":[{"$ref":"#/components/schemas/AuthLinkIdentityRefDto"}]},"issuer":{"type":"string","description":"The issuer of the entity","example":"Sample text"},"subject":{"type":"string","description":"The subject of the entity","example":"Sample text"},"isActive":{"type":"boolean","description":"Whether the record is active"}}},"SessionResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"MyDermaLife IdentityId","format":"uuid"},"identityId":{"type":"string","description":"MyDermaLife IdentityId","format":"uuid"},"subject":{"type":"string","description":"ZITADEL subject — not the business identity"},"issuer":{"type":"string","description":"ZITADEL issuer"},"jitProvisioned":{"type":"boolean","description":"Whether this call created the Identity + AuthLink"},"isActive":{"type":"boolean"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","identityId","subject","issuer","jitProvisioned"]},"CreateCommandInboxDto":{"type":"object","properties":{"idempotencyKey":{"type":"string","description":"The idempotency key of the entity","example":"Sample text"},"scope":{"type":"string","description":"The scope of the entity","example":"Sample text"},"requestHash":{"type":"string","description":"The request hash of the entity","example":"Sample text"},"responseStatus":{"type":"number","description":"The response status of the entity","example":"42"},"responseBody":{"type":"object","description":"The response body of the entity"},"resourceId":{"type":"string","description":"The resource id of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},"expiresAt":{"format":"date-time","type":"string","description":"The expires at of the entity"}},"required":["idempotencyKey","scope","expiresAt"]},"CommandInboxResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier","format":"uuid"},"idempotencyKey":{"type":"string","description":"The idempotency key of the entity","example":"Sample text"},"scope":{"type":"string","description":"The scope of the entity","example":"Sample text"},"requestHash":{"type":"string","description":"The request hash of the entity","example":"Sample text"},"responseStatus":{"type":"number","description":"The response status of the entity","example":"42"},"responseBody":{"type":"object","description":"The response body of the entity"},"resourceId":{"type":"string","description":"The resource id of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},"expiresAt":{"format":"date-time","type":"string","description":"The expires at of the entity"},"isActive":{"type":"boolean","description":"Whether the record is active"},"createdAt":{"format":"date-time","type":"string","description":"Creation timestamp"},"updatedAt":{"format":"date-time","type":"string","description":"Last update timestamp"}},"required":["id","idempotencyKey","scope","requestHash","responseStatus","responseBody","resourceId","expiresAt","isActive","createdAt","updatedAt"]},"UpdateCommandInboxDto":{"type":"object","properties":{"idempotencyKey":{"type":"string","description":"The idempotency key of the entity","example":"Sample text"},"scope":{"type":"string","description":"The scope of the entity","example":"Sample text"},"requestHash":{"type":"string","description":"The request hash of the entity","example":"Sample text"},"responseStatus":{"type":"number","description":"The response status of the entity","example":"42"},"responseBody":{"type":"object","description":"The response body of the entity"},"resourceId":{"type":"string","description":"The resource id of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},"expiresAt":{"format":"date-time","type":"string","description":"The expires at of the entity"},"isActive":{"type":"boolean","description":"Whether the record is active"}}}}}}