openapi: 3.1.0 info: title: Amigo Account Surface Patient API version: 0.1.0 servers: - url: https://api.amigo.ai - url: https://internal-api.amigo.ai - url: https://api-eu-central-1.amigo.ai - url: https://api-ap-southeast-2.amigo.ai - url: https://api-ca-central-1.amigo.ai security: - Bearer-Authorization: [] Bearer-Authorization-Organization: [] Basic: [] tags: - name: Surface Patient paths: /s/f/{surface_id}: get: tags: - Surface Patient summary: Redirect To Surface description: '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.' 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' /s/{token}/lookup/{lookup_type}: get: tags: - Surface Patient summary: Lookup Field description: '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.' 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 /s/{token}/ocr: post: tags: - Surface Patient summary: Ocr Extract description: '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.' 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' '429': description: Rate limited '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /s/{token}: get: tags: - Surface Patient summary: Render Surface description: 'Render a patient-facing surface as HTML. Token-authenticated — no Bearer auth required. Records 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 '429': description: Rate limited '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /s/{token}/spec: get: tags: - Surface Patient summary: Get Surface Spec description: '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.' 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' '429': description: Rate limited '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /s/{token}/availability: get: tags: - Surface Patient summary: Get Availability description: 'Return available appointment slots for the surface''s workspace. Queries FHIR Slot resources from world.entities_synced that are free and within 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 /s/{token}/book: post: tags: - Surface Patient summary: Book Appointment description: '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.' 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 /s/{token}/heal: post: tags: - Surface Patient summary: Heal Field description: '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.' 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' '429': description: Rate limited '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /s/{token}/submit: post: tags: - Surface Patient summary: Submit Surface description: 'Submit a patient-facing surface form. Accepts standard HTML form POST. Writes surface.submitted event with 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 '429': description: Rate limited '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /s/{token}/fields/{key}: put: tags: - Surface Patient summary: Save Field description: 'Auto-save a single field value. Called by client-side JavaScript on field blur. Writes 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' '429': description: Rate limited '500': description: Save failed content: application/json: schema: $ref: '#/components/schemas/SurfaceErrorResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' components: schemas: 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. OcrResponse: properties: extracted_fields: additionalProperties: true type: object title: Extracted Fields confidence: type: number maximum: 1.0 minimum: 0.0 title: Confidence type: object required: - confidence title: OcrResponse description: Structured field extraction result for an uploaded image. 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 HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError 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. Frontend (forms-app) reads ``error_code`` for branching and ``message`` for user-visible copy. ``reason`` is a debug-only field set by the token validator. ``details`` is set when a request body fails server-side validation.' 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 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. FieldSaveRequest: properties: value: title: Value description: The field value to save type: object required: - value title: FieldSaveRequest 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 SaveFieldResponse: properties: status: type: string const: saved title: Status default: saved type: object title: SaveFieldResponse description: Acknowledgement returned when a field is auto-saved. 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 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.0 minimum: 0.0 title: Confidence type: object required: - corrected_value - confidence title: HealFieldResponse 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 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. Free-form by design: ``fields``/``sections``/``branding`` are forwarded from the upstream surface document as raw dicts. Renamed from ``SurfaceSpec`` to avoid an OpenAPI schema-name collision with ``platform_lib.surfaces.models.SurfaceSpec`` (which would otherwise force FastAPI to namespace both classes and rename the existing ``SurfaceSpec`` schema in the committed openapi.json).' 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. 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. 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 securitySchemes: Bearer-Authorization: type: http scheme: bearer bearerFormat: JWT description: Amigo issued JWT token that identifies an user. It's issued either after logging in through the frontend, or manually through the [`SignInWithAPIKey`](sign-in-with-api-key) endpoint. Bearer-Authorization-Organization: type: apiKey in: header name: X-ORG-ID description: An optional organization identifier that indicates from which organization the token is issued. This is used in rare cases where the user to authenticate is making a request for resources in another organization. Basic: type: http scheme: basic description: The username should be set to {org_id}_{user_id}, and the password should be the Amigo issued JWT token that identifies the user.