# Surface Patient

## Redirect To Surface

> Short-URL redirect: \`\`/s/f/{surface\_id}\`\` → \`\`/s/{token}\`\`.\
> \
> Generates a fresh HMAC token and issues a 302 redirect so that SMS\
> messages can contain a short, clickable link instead of the long\
> base64-encoded token URL.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/f/{surface_id}":{"get":{"tags":["Surface Patient"],"summary":"Redirect To Surface","description":"Short-URL redirect: ``/s/f/{surface_id}`` → ``/s/{token}``.\n\nGenerates a fresh HMAC token and issues a 302 redirect so that SMS\nmessages can contain a short, clickable link instead of the long\nbase64-encoded token URL.","operationId":"redirect-to-surface","parameters":[{"name":"surface_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Surface Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"302":{"description":"Redirect to full surface URL"},"404":{"description":"Surface not found"},"410":{"description":"Surface expired"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

## Lookup Field

> Search healthcare reference data for form field autocompletion.\
> \
> Supports: medication (RxNorm), allergy (RxNorm), pharmacy (NPPES NPI),\
> insurance (static carrier list). Token-authenticated, no Bearer auth.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"LookupResponse":{"properties":{"results":{"items":{"additionalProperties":true,"type":"object"},"type":"array","maxItems":200,"title":"Results"}},"type":"object","title":"LookupResponse","description":"Autocompletion results for a surface lookup field."},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."}}},"paths":{"/s/{token}/lookup/{lookup_type}":{"get":{"tags":["Surface Patient"],"summary":"Lookup Field","description":"Search healthcare reference data for form field autocompletion.\n\nSupports: medication (RxNorm), allergy (RxNorm), pharmacy (NPPES NPI),\ninsurance (static carrier list). Token-authenticated, no Bearer auth.","operationId":"lookup-surface-field","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"lookup_type","in":"path","required":true,"schema":{"type":"string","title":"Lookup Type"}},{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":200,"title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Invalid lookup type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Ocr Extract

> Extract structured data from an image (e.g. insurance card) using Gemini Vision.\
> \
> Returns extracted field key-value pairs and a confidence score.\
> Token-authenticated, no Bearer auth.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"OcrRequest":{"properties":{"image":{"type":"string","maxLength":10000000,"minLength":1,"title":"Image","description":"Base64-encoded image data"},"target_fields":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":50},{"type":"null"}],"title":"Target Fields","description":"Optional list of field keys to extract"}},"type":"object","required":["image"],"title":"OcrRequest"},"OcrResponse":{"properties":{"extracted_fields":{"additionalProperties":true,"type":"object","title":"Extracted Fields"},"confidence":{"type":"number","maximum":1,"minimum":0,"title":"Confidence"}},"type":"object","required":["confidence"],"title":"OcrResponse","description":"Structured field extraction result for an uploaded image."},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}/ocr":{"post":{"tags":["Surface Patient"],"summary":"Ocr Extract","description":"Extract structured data from an image (e.g. insurance card) using Gemini Vision.\n\nReturns extracted field key-value pairs and a confidence score.\nToken-authenticated, no Bearer auth.","operationId":"ocr-surface-extract","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcrResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Render Surface

> Render a patient-facing surface as HTML.\
> \
> Token-authenticated — no Bearer auth required.\
> Records a surface.opened lifecycle event on first view.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}":{"get":{"tags":["Surface Patient"],"summary":"Render Surface","description":"Render a patient-facing surface as HTML.\n\nToken-authenticated — no Bearer auth required.\nRecords a surface.opened lifecycle event on first view.","operationId":"render-surface","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Invalid token"},"410":{"description":"Token expired"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Get Surface Spec

> Return surface spec as JSON for the forms app.\
> \
> The forms app (Next.js) calls this on SSR to fetch the spec,\
> saved field values, and merged branding. Records surface.opened\
> event on first access.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"SurfaceSpecResponse":{"properties":{"surface_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Surface Id"},"entity_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Entity Id"},"status":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Status"},"spec":{"$ref":"#/components/schemas/PatientSurfaceSpec"},"saved_values":{"additionalProperties":true,"type":"object","title":"Saved Values"}},"type":"object","required":["spec"],"title":"SurfaceSpecResponse","description":"Surface render bundle returned to forms-app SSR."},"PatientSurfaceSpec":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Description"},"fields":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Fields"},"sections":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Sections"},"branding":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Branding"},"submit_button_text":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Submit Button Text"},"completion_title":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Completion Title"},"completion_message":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Completion Message"},"completion_action_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Completion Action Url"},"context":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Context"}},"type":"object","title":"PatientSurfaceSpec","description":"Patient-facing surface spec — what forms-app renders.\n\nFree-form by design: ``fields``/``sections``/``branding`` are forwarded\nfrom the upstream surface document as raw dicts. Renamed from\n``SurfaceSpec`` to avoid an OpenAPI schema-name collision with\n``platform_lib.surfaces.models.SurfaceSpec`` (which would otherwise\nforce FastAPI to namespace both classes and rename the existing\n``SurfaceSpec`` schema in the committed openapi.json)."},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}/spec":{"get":{"tags":["Surface Patient"],"summary":"Get Surface Spec","description":"Return surface spec as JSON for the forms app.\n\nThe forms app (Next.js) calls this on SSR to fetch the spec,\nsaved field values, and merged branding. Records surface.opened\nevent on first access.","operationId":"get-surface-spec","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceSpecResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"404":{"description":"Surface not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"409":{"description":"Already submitted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"410":{"description":"Token expired or surface archived","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Get Availability

> Return available appointment slots for the surface's workspace.\
> \
> Queries FHIR Slot resources from world.entities that are free and\
> within the requested date range. Token-authenticated, no Bearer auth.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"AvailabilityResponse":{"properties":{"dates":{"items":{"$ref":"#/components/schemas/AvailabilityDate"},"type":"array","maxItems":64,"title":"Dates"}},"type":"object","title":"AvailabilityResponse","description":"Available appointment slots grouped by date."},"AvailabilityDate":{"properties":{"date":{"type":"string","maxLength":16,"title":"Date"},"slots":{"items":{"$ref":"#/components/schemas/AvailabilitySlot"},"type":"array","maxItems":200,"title":"Slots"}},"type":"object","required":["date"],"title":"AvailabilityDate"},"AvailabilitySlot":{"properties":{"id":{"type":"string","maxLength":128,"title":"Id"},"start":{"type":"string","maxLength":16,"title":"Start"},"end":{"type":"string","maxLength":16,"title":"End"},"provider":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"title":"Provider"}},"type":"object","required":["id","start","end"],"title":"AvailabilitySlot"},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."}}},"paths":{"/s/{token}/availability":{"get":{"tags":["Surface Patient"],"summary":"Get Availability","description":"Return available appointment slots for the surface's workspace.\n\nQueries FHIR Slot resources from world.entities that are free and\nwithin the requested date range. Token-authenticated, no Bearer auth.","operationId":"get-surface-availability","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date (YYYY-MM-DD) to start search","title":"Date"},"description":"ISO date (YYYY-MM-DD) to start search"},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":30,"minimum":1,"description":"Number of days to search forward","default":7,"title":"Days"},"description":"Number of days to search forward"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"410":{"description":"Token expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Invalid date format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Book Appointment

> Submit a booking request for a specific slot.\
> \
> Writes a booking.requested world event tied to the surface's entity.\
> Token-authenticated, no Bearer auth.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"BookingRequest":{"properties":{"slot_id":{"type":"string","maxLength":256,"minLength":1,"title":"Slot Id","description":"The FHIR Slot ID to book"}},"type":"object","required":["slot_id"],"title":"BookingRequest"},"BookingResponse":{"properties":{"status":{"type":"string","const":"pending","title":"Status","description":"Booking lifecycle status."},"message":{"type":"string","maxLength":512,"title":"Message"},"slot_id":{"type":"string","maxLength":256,"title":"Slot Id"}},"type":"object","required":["status","message","slot_id"],"title":"BookingResponse","description":"Acknowledgement returned when a booking request is accepted."},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."}}},"paths":{"/s/{token}/book":{"post":{"tags":["Surface Patient"],"summary":"Book Appointment","description":"Submit a booking request for a specific slot.\n\nWrites a booking.requested world event tied to the surface's entity.\nToken-authenticated, no Bearer auth.","operationId":"book-surface-appointment","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"404":{"description":"Slot not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"409":{"description":"Slot unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"410":{"description":"Token expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Heal Field

> Auto-heal a form field value using Claude Haiku.\
> \
> Best-effort LLM correction — returns original value with confidence 0\
> if the service is unavailable or inference fails.\
> Token-authenticated, no Bearer auth.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"HealFieldRequest":{"properties":{"key":{"type":"string","maxLength":128,"minLength":1,"title":"Key"},"value":{"type":"string","maxLength":2000,"minLength":1,"title":"Value"},"field_type":{"type":"string","maxLength":32,"title":"Field Type"},"label":{"type":"string","maxLength":256,"title":"Label"},"sensitive":{"type":"boolean","title":"Sensitive","default":false},"context":{"additionalProperties":true,"type":"object","title":"Context"}},"type":"object","required":["key","value","field_type","label"],"title":"HealFieldRequest"},"HealFieldResponse":{"properties":{"corrected_value":{"type":"string","maxLength":4000,"title":"Corrected Value"},"explanation":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Explanation"},"confidence":{"type":"number","maximum":1,"minimum":0,"title":"Confidence"}},"type":"object","required":["corrected_value","confidence"],"title":"HealFieldResponse"},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}/heal":{"post":{"tags":["Surface Patient"],"summary":"Heal Field","description":"Auto-heal a form field value using Claude Haiku.\n\nBest-effort LLM correction — returns original value with confidence 0\nif the service is unavailable or inference fails.\nToken-authenticated, no Bearer auth.","operationId":"heal-surface-field","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealFieldRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealFieldResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Submit Surface

> Submit a patient-facing surface form.\
> \
> Accepts standard HTML form POST. Writes surface.submitted event\
> with confidence 0.5 (self-reported data).

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}/submit":{"post":{"tags":["Surface Patient"],"summary":"Submit Surface","description":"Submit a patient-facing surface form.\n\nAccepts standard HTML form POST. Writes surface.submitted event\nwith confidence 0.5 (self-reported data).","operationId":"submit-surface","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"401":{"description":"Invalid token"},"409":{"description":"Already submitted"},"410":{"description":"Token expired"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"}}}}}}
```

## Save Field

> Auto-save a single field value.\
> \
> Called by client-side JavaScript on field blur.\
> Writes surface.field\_saved event with confidence 0.5.

```json
{"openapi":"3.1.0","info":{"title":"Platform API","version":"1.0.0"},"servers":[{"url":"https://api.platform.amigo.ai","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key issued via `POST /v1/{workspace_id}/api-keys`. Pass the returned `api_key` value as a Bearer token."}},"schemas":{"FieldSaveRequest":{"properties":{"value":{"title":"Value","description":"The field value to save"}},"type":"object","required":["value"],"title":"FieldSaveRequest"},"SaveFieldResponse":{"properties":{"status":{"type":"string","const":"saved","title":"Status","default":"saved"}},"type":"object","title":"SaveFieldResponse","description":"Acknowledgement returned when a field is auto-saved."},"SurfaceErrorResponse":{"properties":{"error_code":{"type":"string","maxLength":64,"title":"Error Code","description":"Machine-readable error code."},"message":{"anyOf":[{"type":"string","maxLength":1024},{"type":"null"}],"title":"Message","description":"Human-readable error message. Omitted for token-validator errors that only carry ``reason``."},"reason":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Reason","description":"Debug detail from the token validator (e.g. ``token expired``)."},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details","description":"Optional structured validation details for 422 responses."}},"type":"object","required":["error_code"],"title":"SurfaceErrorResponse","description":"Error envelope returned by patient-facing surface JSON endpoints.\n\nFrontend (forms-app) reads ``error_code`` for branching and ``message``\nfor user-visible copy. ``reason`` is a debug-only field set by the token\nvalidator. ``details`` is set when a request body fails server-side\nvalidation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/s/{token}/fields/{key}":{"put":{"tags":["Surface Patient"],"summary":"Save Field","description":"Auto-save a single field value.\n\nCalled by client-side JavaScript on field blur.\nWrites surface.field_saved event with confidence 0.5.","operationId":"save-surface-field","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"key","in":"path","required":true,"schema":{"type":"string","title":"Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldSaveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveFieldResponse"}}}},"401":{"description":"Invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limited"},"500":{"description":"Save failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SurfaceErrorResponse"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.amigo.ai/api-reference/readme/platform/surface-patient.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
