{"openapi":"3.1.0","info":{"title":"Harny API","summary":"Identity API with key-scoped vault operations","version":"0.1.0"},"paths":{"/health":{"get":{"tags":["health","public"],"summary":"Get Health","description":"Public liveness probe.\n\nIntentionally returns no dependency topology details.","operationId":"get_health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Get Health Health Get"}}}}},"security":[]}},"/v1/users":{"post":{"tags":["users"],"summary":"Create User","description":"Provision a new user account and return a one-time API key.","operationId":"create_user_v1_users_post","parameters":[{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/users/me/erasure-status":{"get":{"tags":["users"],"summary":"Get Current User Erasure Status","description":"Return the latest erasure job for the authenticated user, or 404 if none.","operationId":"get_current_user_erasure_status_v1_users_me_erasure_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDataEraseStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/users/me/data":{"delete":{"tags":["users"],"summary":"Erase Current User Data","description":"Self-serve erasure of the authenticated user's data (GDPR Article 17).","operationId":"erase_current_user_data_v1_users_me_data_delete","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDataEraseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/users/{user_id}/data":{"delete":{"tags":["users"],"summary":"Erase User Data","description":"Admin/app-initiated erasure of a specific user's data (GDPR Article 17).","operationId":"erase_user_data_v1_users__user_id__data_delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"User Id"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDataEraseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/apps/{app_id}/claim-link":{"post":{"tags":["apps","public"],"summary":"Request Claim Link","description":"Workstream E — re-issue a fresh one-time claim URL for the authenticated app. Auth: Bearer fsa_ (the app's own key). Use when the URL relayed by an earlier `provision_app` call expired or was lost. Does NOT create a new app. The URL is not an API key.","operationId":"request_claim_link_v1_apps__app_id__claim_link_post","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[]}},"/v1/apps/claim":{"post":{"tags":["apps","public"],"summary":"Redeem Claim","description":"Workstream E — bind ownership of a pre-account app to the signed-in Clerk user. Auth: X-Clerk-BFF-Session. The body carries the raw claim token from the URL's ?token= param — never logged in full. Single-use: a second redeem of the same token returns `claim_token_expired`, except for the person who owns the app because of it, who gets the same success again. A signed-in person who claims an app whose owner is only an end user the agent made earlier becomes the owner.","operationId":"redeem_claim_v1_apps_claim_post","parameters":[{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRedeemRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[]}},"/v1/users/me/data-requests":{"post":{"tags":["privacy"],"summary":"Create My Data Request","description":"File an access, deletion, correction or objection request with Harny for the acting end user, or a request to stop sharing facts with their other apps. The request is answered by the date in due_at. An objection, and a withdrawal from sharing, take effect at once; a withdrawal of an objection takes effect once Harny has checked with the end user, and cannot be sent with the app key.","operationId":"create_my_data_request_v1_users_me_data_requests_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataRequestCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataRequestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["privacy"],"summary":"List My Data Requests","description":"List the acting end user's data requests and where each one stands.","operationId":"list_my_data_requests_v1_users_me_data_requests_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataRequestListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/apps/{app_id}/setup-bundle":{"get":{"tags":["apps"],"summary":"Get Setup Bundle","description":"The setup bundle for this app's agent: facts, key-handling rules (variable names, never values), sources to connect, the acting policy as the business set it, the model preset, deploy recipes and the starter config. shape=common:<path id> for a common setup path; shape=developer with selections for a developer-specific setup (use POST for a long description). format=prompt returns the instructions as markdown; format=skill returns an installable agent-skill folder as a zip.","operationId":"get_setup_bundle_v1_apps__app_id__setup_bundle_get","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"shape","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":40,"description":"common:<path id> or developer","title":"Shape"},"description":"common:<path id> or developer"},{"name":"preset","in":"query","required":false,"schema":{"anyOf":[{"enum":["cost_first","quality_first","regulated"],"type":"string"},{"type":"null"}],"title":"Preset"}},{"name":"deploy_target","in":"query","required":false,"schema":{"enum":["cloud_run","render","docker","unspecified"],"type":"string","default":"unspecified","title":"Deploy Target"}},{"name":"surface","in":"query","required":false,"schema":{"anyOf":[{"enum":["chat_page","email","webhook_only"],"type":"string"},{"type":"null"}],"title":"Surface"}},{"name":"sources","in":"query","required":false,"schema":{"type":"array","items":{"enum":["gmail","calendar","drive","notion","slack","email_bridge"],"type":"string"},"title":"Sources"}},{"name":"actions","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"title":"Actions"}},{"name":"email_arrival_trigger","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Arrival Trigger"}},{"name":"description","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Description"}},{"name":"format","in":"query","required":false,"schema":{"enum":["json","skill","prompt"],"type":"string","default":"json","title":"Format"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupBundleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"post":{"tags":["apps"],"summary":"Post Setup Bundle","description":"Same bundle as the GET, with the request in the body, for a developer-specific setup with a longer description. It returns the bundle; it does not change the app's acting policy, sources or keys.","operationId":"post_setup_bundle_v1_apps__app_id__setup_bundle_post","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"format","in":"query","required":false,"schema":{"enum":["json","skill","prompt"],"type":"string","default":"json","title":"Format"}},{"name":"X-Admin-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Admin-Key"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupBundleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupBundleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/ingest":{"post":{"tags":["vault"],"summary":"Ingest Source","description":"Ingest content from a URL into the authenticated user's vault.","operationId":"ingest_source_v1_vault_ingest_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultIngestRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultIngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/ingest/file":{"post":{"tags":["vault"],"summary":"Ingest File","description":"Ingest an uploaded file (PDF, DOCX, text, etc.) into the user's vault.","operationId":"ingest_file_v1_vault_ingest_file_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_ingest_file_v1_vault_ingest_file_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultIngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/ingest/text":{"post":{"tags":["vault"],"summary":"Ingest Text","description":"Ingest pasted text content into the authenticated user's vault. Returns 202 in both outcomes: normally processing completes inside this request (`status: 'ingested'` — the content is immediately queryable, nothing to poll); if processing takes longer than about 15 seconds, or the memory backend is temporarily degraded, the ingest is accepted and finishes in the background (`status: 'queued'`; `queued_reason` says why when the backend is degraded) and GET /v1/vault/ingest/status tracks it via the returned resource_uri. Send an `Idempotency-Key` header to make retries safe.","operationId":"ingest_text_v1_vault_ingest_text_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional. Send the same value when you retry this request: the repeat returns the original result and is not processed or counted again. Kept for 24 hours.","title":"Idempotency-Key"},"description":"Optional. Send the same value when you retry this request: the repeat returns the original result and is not processed or counted again. Kept for 24 hours."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultTextPasteRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultIngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/push-ingest":{"post":{"tags":["vault"],"summary":"Push Ingest","description":"Accept pre-extracted items from external sources (Apps Script, webhooks).","operationId":"push_ingest_v1_vault_push_ingest_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer hpk_.. or server-side fsk_.. key","title":"Authorization"},"description":"Bearer hpk_.. or server-side fsk_.. key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultPushIngestRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultPushIngestResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/ingest/status":{"get":{"tags":["vault"],"summary":"Ingest Source Status","description":"Check the processing status of a previously submitted ingest job. Answers 404 with `error_code: ingestion_not_found` for a resource_uri this user was never given, or one that no longer exists.","operationId":"ingest_source_status_v1_vault_ingest_status_get","parameters":[{"name":"resource_uri","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Resource URI from POST /vault/ingest","title":"Resource Uri"},"description":"Resource URI from POST /vault/ingest"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultIngestStatusResponse"}}}},"404":{"description":"No ingest was found for this resource_uri (`ingestion_not_found`)."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/query":{"post":{"tags":["vault"],"summary":"Query Vault","description":"Search the user's Harny Smart Profiles context across Home Context and eligible Shared Context results. Home Context is the requesting app's own detailed context. Shared Context is abstracted shared-fact text from other apps, partitioned as Shared Context (verified) and Shared Context (unverified) by source trust. Linked results use opaque read handles rather than exposing peer user identifiers, and Shared Context text is served as policy-projected safe representation rather than unrestricted raw provider payload. The L0/L1/L2 read-depth system is separate from, and not the same as, the Home/Shared origin-scope system. This endpoint returns context only. Current context-sync providers are governed by a declared read-only contract plus regression tests; this endpoint is not an action surface. If an app or agent uses the returned information to take actions in another system, those downstream actions occur outside Harny's execution plane and are not observed or governed unless they later pass through Harny tool execution APIs.","operationId":"query_vault_v1_vault_query_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultQueryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/search":{"post":{"tags":["vault"],"summary":"Search Vault","description":"Search the vault. Alias for POST /v1/vault/query — the path most developers try first. Identical request, response, and semantics.","operationId":"search_vault_v1_vault_search_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultQueryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/browse":{"get":{"tags":["vault"],"summary":"Browse Vault","description":"Browse vault contents for the authenticated user at a given path.","operationId":"browse_vault_v1_vault_browse_get","parameters":[{"name":"path","in":"query","required":false,"schema":{"type":"string","description":"Directory path to browse","default":"/","title":"Path"},"description":"Directory path to browse"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultBrowseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/vault/read/{resource_path}":{"get":{"tags":["vault"],"summary":"Read Resource","description":"Read the content of one memory resource from the user's vault.","operationId":"read_resource_v1_vault_read__resource_path__get","parameters":[{"name":"resource_path","in":"path","required":true,"schema":{"type":"string","title":"Resource Path"}},{"name":"level","in":"query","required":false,"schema":{"anyOf":[{"enum":["l0","l1","l2"],"type":"string"},{"type":"null"}],"title":"Level"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VaultReadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context/assemble":{"post":{"tags":["context"],"summary":"Assemble Context","description":"Assemble ready-to-inject Smart Profiles context blocks for the authenticated user. Application scope is derived from the authenticated principal, not caller input. Home Context is the requesting app's own detailed context. Shared Context is abstracted shared-fact text from other apps and is included only when live vault-link category policy and shared-context participation allow it. Shared Context is partitioned into Shared Context (verified) and Shared Context (unverified) by source trust. Linked context references are returned as opaque handles; peer user identifiers are not exposed. Shared Context blocks use policy-projected safe text, and assembly applies a central policy gate before token budgeting. The L0/L1/L2 read-depth system is separate from, and not the same as, the Home/Shared origin-scope system. This endpoint returns context only; downstream actions taken elsewhere remain outside Harny visibility unless they later pass through Harny execution APIs.","operationId":"assemble_context_v1_context_assemble_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextAssembleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextAssembleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context/suppress":{"post":{"tags":["context"],"summary":"Add Suppression","description":"Add a suppression rule to filter blocks from future context assemblies.","operationId":"add_suppression_v1_context_suppress_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionRuleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuppressionRuleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["context"],"summary":"List Suppressions","description":"List all active suppression rules for the authenticated user.","operationId":"list_suppressions_v1_context_suppress_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SuppressionRuleResponse"},"title":"Response List Suppressions V1 Context Suppress Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context/suppress/{rule_id}":{"delete":{"tags":["context"],"summary":"Delete Suppression","description":"Delete one suppression rule owned by the authenticated user.","operationId":"delete_suppression_v1_context_suppress__rule_id__delete","parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","title":"Rule Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Delete Suppression V1 Context Suppress Rule Id Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/conflicts/asked":{"post":{"tags":["conflicts"],"summary":"Report that a conflict was asked about","description":"Report that you asked the user about this conflict. Harny remembers it, so the context response marks the conflict asked and the question is not put twice. Only a conflict from this user's context response can be reported.","operationId":"report_conflict_asked_v1_conflicts_asked_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConflictRef"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConflictAskedResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/conflicts/answer":{"post":{"tags":["conflicts"],"summary":"Send the user's answer to a conflict","description":"Send the user's answer to a conflict. It is saved as something the user said, the same way POST /v1/vault/ingest/text saves text, and the conflict is no longer returned. Only a conflict from this user's context response can be answered.","operationId":"answer_conflict_v1_conflicts_answer_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConflictAnswerRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConflictAnswerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context-sources/{provider}/connect":{"post":{"tags":["context-sources"],"summary":"Start Context Source Connect","description":"Start OAuth flow to connect a context source (Gmail, Notion, etc.).","operationId":"start_context_source_connect_v1_context_sources__provider__connect_post","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":32,"title":"Provider"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceConnectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceConnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context-sources":{"get":{"tags":["context-sources"],"summary":"List Context Sources","description":"List all context-source connections for the authenticated user.","operationId":"list_context_sources_v1_context_sources_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}},{"name":"X-Harny-App-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Harny-App-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context-sources/{provider}/sync":{"post":{"tags":["context-sources"],"summary":"Trigger Context Source Sync","description":"Trigger a manual sync of a connected context source for the user.","operationId":"trigger_context_source_sync_v1_context_sources__provider__sync_post","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":32,"title":"Provider"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceSyncRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceSyncResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context-sources/{provider}":{"delete":{"tags":["context-sources"],"summary":"Disconnect Context Source","description":"Disconnect a context source and optionally delete its synced data.","operationId":"disconnect_context_source_v1_context_sources__provider__delete","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":32,"title":"Provider"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ContextSourceDisconnectRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextSourceDisconnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/context-sources/{provider}/reauth-url":{"get":{"tags":["context-sources"],"summary":"Get Reauth Url","description":"Return a short-lived re-auth URL for an existing connection's expired tokens.","operationId":"get_reauth_url_v1_context_sources__provider__reauth_url_get","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":32,"title":"Provider"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key","title":"Authorization"},"description":"Bearer fsa_.. app key (with X-Harny-User) or fsk_.. user key"},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key.","title":"X-Harny-User"},"description":"End user to act for. Harny user id, or the identifier your app registered the user with. Required with an fsa_ app key; ignored with an fsk_ user key."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"X-Clerk-BFF-Session","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Clerk-Bff-Session"}},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Reauth Url V1 Context Sources Provider Reauth Url Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/auth/provision":{"post":{"tags":["harness","public"],"summary":"Provision App Endpoint","description":"Provision a new application and receive an app API key (fsa_ prefix). No authentication required. Rate limited to 5 calls per IP per hour. Use the returned app_api_key as a Bearer token to provision users via POST /users, then switch to the user key (fsk_ prefix) for OAuth and context assembly.","operationId":"provision_app_endpoint_v1_auth_provision_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthProvisionRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthProvisionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"security":[]}},"/v1/actions":{"post":{"tags":["actions","actions"],"summary":"Create Action Record","description":"Record one action a developer's agent took, and what came of it. Auth: Bearer ``fsa_`` app key; ``X-Harny-User`` names the end user the action was about, or is omitted for an app-scoped action. Returns the stored record's id, whether it was deduplicated by ``idempotency_key``, the structured ``failure_class`` and ``retry_posture`` derived from ``error_code`` / ``http_status``, and the count of secret-shaped substrings the scrubber removed.","operationId":"create_action_record_v1_actions_post","parameters":[{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user.","title":"X-Harny-User"},"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionRecordWriteRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionRecordWriteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["actions","actions"],"summary":"List Action Records","description":"Page an app's action records for a developer's admin interface. Auth: Bearer ``fsa_`` app key — the credential authorises the entire list (no per-user key can, because the list spans users). Returns the newest actions first with an opaque ``next_cursor``; pass the cursor back verbatim as the ``cursor`` query param to fetch the next page. ``scope=user|app`` narrows to just user-scoped or just app-scoped rows; ``user_id`` narrows to one subject.","operationId":"list_action_records_v1_actions_get","parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string","description":"Subject scope: `all` | `user` (only user-scoped rows) | `app` (only app-scoped rows).","default":"all","title":"Scope"},"description":"Subject scope: `all` | `user` (only user-scoped rows) | `app` (only app-scoped rows)."},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Narrow to one end user. ANDs with the calling app; a foreign id returns an empty page.","title":"User Id"},"description":"Narrow to one end user. ANDs with the calling app; a foreign id returns an empty page."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"One of processing|completed|partial|failed.","title":"Status"},"description":"One of processing|completed|partial|failed."},{"name":"failure_class","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Structured failure class to filter on (e.g. `rate_limited`, `auth_expired`).","title":"Failure Class"},"description":"Structured failure class to filter on (e.g. `rate_limited`, `auth_expired`)."},{"name":"correlation_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Group the actions of one agent run together.","title":"Correlation Id"},"description":"Group the actions of one agent run together."},{"name":"target","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Exact `target` string to filter on (e.g. `profile.update`).","title":"Target"},"description":"Exact `target` string to filter on (e.g. `profile.update`)."},{"name":"target_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"description":"Case-insensitive substring of `target` (e.g. `update`). A FILTER, not a search: no ranking, no term splitting, no semantic match. An empty page means no target was spelled that way.","title":"Target Contains"},"description":"Case-insensitive substring of `target` (e.g. `update`). A FILTER, not a search: no ranking, no term splitting, no semantic match. An empty page means no target was spelled that way."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Only include actions whose `occurred_at` is at or after this UTC timestamp.","title":"Since"},"description":"Only include actions whose `occurred_at` is at or after this UTC timestamp."},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Only include actions whose `occurred_at` is at or before this UTC timestamp.","title":"Until"},"description":"Only include actions whose `occurred_at` is at or before this UTC timestamp."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Page size, 1.200. Clamped to 200.","default":50,"title":"Limit"},"description":"Page size, 1.200. Clamped to 200."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor returned as `next_cursor` from a previous call.","title":"Cursor"},"description":"Opaque cursor returned as `next_cursor` from a previous call."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionRecordListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/actions/export":{"get":{"tags":["actions","actions"],"summary":"Export Action Records","description":"Export an app's action records as a document you can hand to a client, an insurer or a regulator: when each action happened, what the agent was asked to do, for which end user, under which permission, what happened, what failed and what was undone. Auth: Bearer ``fsa_`` app key. ``user_id`` limits the export to one end user; ``from`` / ``to`` bracket when the action happened. JSON is the canonical form; ``format=csv`` returns the same rows as a spreadsheet. Every export carries the retention statement from the platform's current settings and the app's newest sequence position. ``verify=true`` also walks the app's numbered sequence and hash chain and reports ``gap_free`` and ``chain_ok``; send an earlier export's ``ledger`` values as ``anchor_sequence`` / ``anchor_hash`` to check that nothing up to that point was rewritten since.","operationId":"export_action_records_v1_actions_export_get","parameters":[{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Limit to one end user (Harny user id). ANDs with the calling app; a foreign id exports nothing.","title":"User Id"},"description":"Limit to one end user (Harny user id). ANDs with the calling app; a foreign id exports nothing."},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Only actions that happened at or after this time (ISO 8601, UTC).","title":"From"},"description":"Only actions that happened at or after this time (ISO 8601, UTC)."},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Only actions that happened at or before this time (ISO 8601, UTC).","title":"To"},"description":"Only actions that happened at or before this time (ISO 8601, UTC)."},{"name":"format","in":"query","required":false,"schema":{"enum":["json","csv"],"type":"string","description":"``json`` (canonical) or ``csv`` (the same rows for a spreadsheet).","default":"json","title":"Format"},"description":"``json`` (canonical) or ``csv`` (the same rows for a spreadsheet)."},{"name":"verify","in":"query","required":false,"schema":{"type":"boolean","description":"Also check the app's numbered sequence and hash chain.","default":false,"title":"Verify"},"description":"Also check the app's numbered sequence and hash chain."},{"name":"anchor_sequence","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"With ``verify=true``: a ``head_sequence`` from an earlier export.","title":"Anchor Sequence"},"description":"With ``verify=true``: a ``head_sequence`` from an earlier export."},{"name":"anchor_hash","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":64,"maxLength":64,"pattern":"^[0-9a-fA-F]{64}$"},{"type":"null"}],"description":"With ``verify=true``: the ``head_chain_hash`` from the same earlier export.","title":"Anchor Hash"},"description":"With ``verify=true``: the ``head_chain_hash`` from the same earlier export."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"JSON (the default) is the canonical export. With ``format=csv`` the same rows come back as a spreadsheet file whose first row is plain-words column names; the manifest, retention statement and verification result travel in ``X-Harny-*`` response headers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionRecordExportResponse"}},"text/csv":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/handoffs":{"post":{"tags":["handoffs"],"summary":"Create Handoff","description":"Ask for a person, only when one is truly needed: name why with `because` (one of eight codes) and what your agent tried with `tried`. The door sends a step that belongs to the end user back to the user, a code or set-up fault to the coding assistant, and a step the business's staff take to the staff tool it connected; a request that does none of these is turned back with the next step. Name the end user with X-Harny-User. Raises the handoff.needed webhook. Recorded.","operationId":"create_handoff_v1_handoffs_post","parameters":[{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user.","title":"X-Harny-User"},"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffCreateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"get":{"tags":["handoffs"],"summary":"List Handoffs","description":"The handoff inbox, most recently active first. App key; send X-Harny-User to narrow it to one end user.","operationId":"list_handoffs_v1_handoffs_get","parameters":[{"name":"state","in":"query","required":false,"schema":{"enum":["open","resolved","all"],"type":"string","default":"open","title":"State"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Cursor"}},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user.","title":"X-Harny-User"},"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/handoffs/{handoff_id}":{"get":{"tags":["handoffs"],"summary":"Get Handoff","description":"One handoff of this app.","operationId":"get_handoff_v1_handoffs__handoff_id__get","parameters":[{"name":"handoff_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"The handoff id from the inbox or a handoff.needed event.","title":"Handoff Id"},"description":"The handoff id from the inbox or a handoff.needed event."},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user.","title":"X-Harny-User"},"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/v1/handoffs/{handoff_id}/resolve":{"post":{"tags":["handoffs"],"summary":"Resolve Handoff","description":"Resolve a handoff: name the person who handled it and what they did. Recorded on the action record as a human step. Never let a model call it.","operationId":"resolve_handoff_v1_handoffs__handoff_id__resolve_post","parameters":[{"name":"handoff_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"The handoff to resolve.","title":"Handoff Id"},"description":"The handoff to resolve."},{"name":"X-Harny-User","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user.","title":"X-Harny-User"},"description":"End user this action is about. Harny user id, or the identifier your app registered the user with. Omit for an app-scoped action (a reindex, a scheduled sweep, a cache warm-up) — never omit it to fall back on the app owner's own user."},{"name":"X-Harny-User-Type","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id.","title":"X-Harny-User-Type"},"description":"Disambiguates X-Harny-User when the same identifier string is registered under more than one identifier_type: email, app_id or device_id."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bearer fsa_.. app key","title":"Authorization"},"description":"Bearer fsa_.. app key"},{"name":"X-Forwarded-For","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Forwarded-For"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffResolveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffResolveResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"default":{"description":"Error response. Carries the envelope at the top level; parse `error_code`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"components":{"schemas":{"ActionRecordEntry":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Record id. Example: ``0f2b04ee-59d3-4b6c-9c6a-8b0f7e1e9c19``."},"user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"User Id","description":"The end user this action was about, or ``null`` for an app-scoped action (a reindex, a scheduled sweep). Example: ``11111111-1111-1111-1111-111111111111``."},"target":{"type":"string","title":"Target","description":"The action's target. Example: ``profile.update``."},"status":{"type":"string","enum":["processing","completed","partial","failed"],"title":"Status","description":"The action's stored outcome. Example: ``completed``."},"actor_type":{"type":"string","title":"Actor Type","description":"Who performed the action, from the platform's own attribution. ``agent`` almost always on this channel. Example: ``agent``."},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At","description":"When the action happened. Example: ``2026-08-19T05:00:12Z``."},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters","description":"The stored (already-scrubbed) parameters. Example: ``{\"user_id\": \"u_123\"}``."},"outcome_summary":{"additionalProperties":true,"type":"object","title":"Outcome Summary","description":"The stored outcome summary. Example: ``{\"rows_updated\": 1}``."},"failure_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Class","description":"Structured failure class, or ``null``. Example: ``rate_limited``."},"retry_posture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retry Posture","description":"Suggested next step for the failure. Example: ``retry_after_fix``."},"failure_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Detail","description":"Short human-readable failure sentence. Example: ``retry-after 30s per upstream``."},"artifact_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Ref","description":"Pointer to the action's large artifact, if any. Example: ``s3://…``."},"correlation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correlation Id","description":"Correlation id that groups a run's actions. Example: ``run_abc``."},"superseded":{"type":"boolean","title":"Superseded","description":"True when a later record's ``supersedes_id`` points at this one. A record Harny wrote about an action it took is never marked replaced by your records. Example: ``false``."},"redaction_count":{"type":"integer","title":"Redaction Count","description":"How many secret-shaped substrings the scrubber removed on the way in. Example: ``0``.","default":0},"redaction_profile":{"additionalProperties":{"additionalProperties":{"type":"integer"},"type":"object"},"type":"object","title":"Redaction Profile","description":"Per-field, per-rule-CLASS provenance for what was redacted, shape ``{field_name: {rule_class: count}}``. Rule classes are ``credential`` (a live credential — the genuine 'agent is passing secrets' tell); ``public_identifier`` (a hit on a shape published in client-side JavaScript by design, e.g. Stripe's ``pk_live_…`` — not evidence of insecurity); and ``personal_data`` (a fact about the end user's data — credit_card / iban / ssn_us — not about the agent's safety). Records the class + count only, never the matched value. Example: ``{\"parameters\": {\"credential\": 1}}``."},"effect":{"type":"string","enum":["read","write","unknown"],"title":"Effect","description":"Stored action-effect: ``read`` | ``write`` | ``unknown``. Never inferred from ``target`` text. A severity amplifier for downstream signal rendering; not a detector. Example: ``write``.","default":"unknown"},"initiated_by":{"type":"string","enum":["user_request","schedule","agent_plan","system_event","unknown"],"title":"Initiated By","description":"Stored causation: what CAUSED this action to be attempted, as distinct from ``actor_type``, which says who PERFORMED it. ``unknown`` is the honest and commonest value — the platform records a cause only when the caller declared one. Example: ``user_request``.","default":"unknown"}},"additionalProperties":false,"type":"object","required":["id","target","status","actor_type","occurred_at","superseded"],"title":"ActionRecordEntry","description":"One row of the management list — an action as a developer sees it."},"ActionRecordExportEndUser":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Harny's id for the end user. Example: ``11111111-1111-1111-1111-111111111111``."},"identifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identifier","description":"The identifier your app registered the end user with. Example: ``acct_123``."},"identifier_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identifier Type","description":"Kind of ``identifier``: ``email``, ``app_id`` or ``device_id``. Example: ``app_id``."}},"additionalProperties":false,"type":"object","required":["id"],"title":"ActionRecordExportEndUser","description":"The end user a record was about."},"ActionRecordExportManifest":{"properties":{"format_version":{"type":"integer","title":"Format Version","description":"Export format version. Example: ``1``."},"kind":{"type":"string","enum":["app","end_user"],"title":"Kind","description":"``app``: every end user of the app. ``end_user``: one end user's own export."},"generated_at":{"type":"string","format":"date-time","title":"Generated At","description":"When the export was produced."},"app_id":{"type":"string","format":"uuid","title":"App Id","description":"The app the records belong to."},"app_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Name","description":"The app's name."},"end_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"End User Id","description":"The end user the export is limited to, if any."},"date_from":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date From","description":"Only records that happened at or after this time."},"date_to":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Date To","description":"Only records that happened at or before this time."},"record_count":{"type":"integer","title":"Record Count","description":"Number of records in ``records``."},"records_sha256":{"type":"string","title":"Records Sha256","description":"SHA-256 of ``records`` serialised as JSON with sorted keys, no whitespace and UTF-8 characters unescaped."}},"additionalProperties":false,"type":"object","required":["format_version","kind","generated_at","app_id","record_count","records_sha256"],"title":"ActionRecordExportManifest","description":"What this export is and how to check it."},"ActionRecordExportPermission":{"properties":{"kinds":{"items":{"type":"string","enum":["nobody_else","others_affected","money","irreversible"]},"type":"array","title":"Kinds","description":"Which kinds of action it was: ``nobody_else``, ``others_affected``, ``money``, ``irreversible``; an action can be more than one kind, and the business chose a rule for each. An action recorded before the four kinds is shown as the kind it was. Example: ``[\"nobody_else\"]``."},"kinds_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kinds Label","description":"``kinds`` in plain words, comma-joined. Example: ``Nobody else affected``."},"kind_reasons":{"items":{"type":"string"},"type":"array","title":"Kind Reasons","description":"Why the action was those kinds. Example: ``[\"own_calendar_no_guests\"]``."},"decided_by":{"anyOf":[{"type":"string","enum":["nobody_else","others_affected","money","irreversible"]},{"type":"null"}],"title":"Decided By","description":"The kind whose rule decided — the most careful of the business's rules for the kinds it was. Example: ``nobody_else``."},"business_rule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Rule","description":"The business's rule that decided the action: ``act``, ``ask_first`` or ``off``; ``null`` when no rule was set. Example: ``act``."},"business_rule_label":{"type":"string","title":"Business Rule Label","description":"``business_rule`` in plain words. Example: ``Act without asking``. When ``policy_source`` is ``proposal`` it reads ``Proposed setting:..``. Example: ``Proposed setting: Act without asking``."},"policy_source":{"type":"string","enum":["business","proposal"],"title":"Policy Source","description":"Whose rule ``business_rule`` is: ``business`` (the business set it) or ``proposal`` (the setup proposed it and the business's owner had not yet set or accepted its own rules). Example: ``business``.","default":"business"},"rule_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rule Version","description":"Version of the business's rules in force. Example: ``3``."},"policy_origin":{"anyOf":[{"type":"string","enum":["owner","learned","preset"]},{"type":"null"}],"title":"Policy Origin","description":"Where the rule that decided came from: ``owner`` (the owner set it), ``learned`` (the owner tapped a line the users' answers earned) or ``preset`` (the setup proposed it). ``null`` on a record made before this was kept, or when no rule was set. Example: ``owner``."},"policy_set_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Policy Set At","description":"When the rule that decided was last written. Example: ``2026-10-14T09:00:00Z``."},"policy_effective_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Policy Effective At","description":"When the rule that decided took effect: the moment its value last changed. Saving the same value again does not move it. ``null`` on a record made before this was kept, or when no change is on record. Example: ``2026-10-03T09:00:00Z``."},"confirmed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confirmed By","description":"Who confirmed an ask-first action, as the credential that sent it proves: ``app`` (the app key, on the end user's behalf), ``end_user_key`` (the end user's API key), ``end_user`` (the person's own signed-in session), or ``null``. Example: ``end_user``."},"confirmed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Confirmed At","description":"When it was confirmed. Example: ``2026-09-22T14:02:11Z``."},"declined_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Declined By","description":"Who declined an ask-first action, as the credential that sent it proves: ``app`` (the app key, on the end user's behalf), ``end_user_key`` (the end user's API key), ``end_user`` (the person's own signed-in session), or ``null``. Example: ``end_user``."},"declined_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Declined At","description":"When it was declined. Example: ``2026-09-22T14:02:11Z``."},"decided_with_key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Decided With Key Id","description":"Id of the API key that sent the confirmation or decline (the app key or the end user's key), or ``null``. Example: ``3f1c9a52-6b8e-4d0a-9c1e-2a7b5d4e8f10``."},"held_for_recipients":{"items":{"type":"string"},"type":"array","title":"Held For Recipients","description":"The addresses the person never gave, when that is why Harny asked the person first although the business's rule was ``act`` (an invitation or message after the agent read someone else's content); empty otherwise. Example: ``[\"someone@example.com\"]``."},"recipient_lookup_failed":{"type":"boolean","title":"Recipient Lookup Failed","description":"True when Harny could not finish checking ``held_for_recipients`` against what the person gave (a look-up failed), so it asked instead; the addresses may well be ones the person gave.","default":false}},"additionalProperties":false,"type":"object","required":["business_rule_label"],"title":"ActionRecordExportPermission","description":"What allowed an action Harny performed: its kinds of action and the business's rule for them.\n\nPresent only on actions Harny performed itself; an action your software\nreported was governed by your own system, which Harny does not see."},"ActionRecordExportResponse":{"properties":{"export":{"$ref":"#/components/schemas/ActionRecordExportManifest"},"retention":{"$ref":"#/components/schemas/ActionRecordRetention"},"ledger":{"anyOf":[{"$ref":"#/components/schemas/ActionRecordLedgerHead"},{"type":"null"}],"description":"The app's newest position. Not included in an end user's own export."},"verification":{"anyOf":[{"$ref":"#/components/schemas/ActionRecordVerification"},{"type":"null"}],"description":"Present when the export was requested with ``verify=true``."},"records":{"items":{"$ref":"#/components/schemas/ActionRecordExportRow"},"type":"array","title":"Records","description":"The records, oldest first."}},"additionalProperties":false,"type":"object","required":["export","retention"],"title":"ActionRecordExportResponse","description":"The action record as a document: manifest, retention, ledger head, verification, rows."},"ActionRecordExportRow":{"properties":{"sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sequence","description":"Position of this record in the app's numbered sequence (1, 2, 3 … with no gaps). Example: ``42``."},"record_id":{"type":"string","format":"uuid","title":"Record Id","description":"The record's id. Example: ``0f2b04ee-59d3-4b6c-9c6a-8b0f7e1e9c19``."},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At","description":"When the action happened. Example: ``2026-09-22T14:02:11Z``."},"recorded_at":{"type":"string","format":"date-time","title":"Recorded At","description":"When Harny recorded it. Example: ``2026-09-22T14:02:11Z``."},"end_user":{"anyOf":[{"$ref":"#/components/schemas/ActionRecordExportEndUser"},{"type":"null"}],"description":"The end user the action was about, or ``null`` for an app-wide action."},"action":{"type":"string","title":"Action","description":"What was acted on. Example: ``calendar.create_event``."},"service_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Label","description":"The service the action ran on, in plain words, when Harny performed it and knows the service. Example: ``Google Calendar``."},"instruction":{"additionalProperties":true,"type":"object","title":"Instruction","description":"What the agent was asked to do: the arguments as stored (secret-shaped values removed). Example: ``{\"title\": \"Planning call\"}``."},"cause":{"type":"string","enum":["user_request","schedule","agent_plan","system_event","unknown"],"title":"Cause","description":"What caused the action to be attempted. Example: ``user_request``."},"cause_label":{"type":"string","title":"Cause Label","description":"``cause`` in plain words. Example: ``A person asked for it``."},"performed_by":{"type":"string","title":"Performed By","description":"Who performed it: ``agent``, ``user``, ``system`` or ``operator`` (a named person at the business). Example: ``agent``."},"performed_by_label":{"type":"string","title":"Performed By Label","description":"``performed_by`` in plain words. Example: ``The business's agent``."},"evidence":{"type":"string","enum":["observed","reported"],"title":"Evidence","description":"``observed``: Harny performed the action and recorded it with its own clock. ``reported``: the business's software reported an action it performed elsewhere. Example: ``observed``."},"evidence_label":{"type":"string","title":"Evidence Label","description":"``evidence`` in plain words."},"credential_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Credential Id","description":"Id of the app key that authenticated the action. Not included in an end user's own export. Example: ``key_abc``."},"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id","description":"Groups the actions of one agent run. Example: ``run_abc``."},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id","description":"Id of Harny's execution request behind an action Harny performed. Example: ``7d0c…``."},"permission":{"anyOf":[{"$ref":"#/components/schemas/ActionRecordExportPermission"},{"type":"null"}],"description":"What allowed the action. Present only on actions Harny performed."},"status":{"type":"string","enum":["processing","completed","partial","failed"],"title":"Status","description":"Stored status. Example: ``completed``."},"outcome":{"type":"string","title":"Outcome","description":"What happened: ``completed``, ``refused``, ``awaiting_end_user``, ``declined``, ``expired``, ``failed``, ``undone``, ``partial`` or ``in_progress``. Example: ``completed``."},"outcome_label":{"type":"string","title":"Outcome Label","description":"``outcome`` in plain words. Example: ``Done``."},"artifact_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Ref","description":"Reference to what the action produced. Example: ``evt0001``."},"link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link","description":"Link to the result, when there is one."},"failure_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Code","description":"Structured code for why the action was refused or failed. Example: ``acting_policy_unset``."},"failure_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Class","description":"Category of the failure. Example: ``permission_denied``."},"failure_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Label","description":"The failure in plain words. Example: ``The business has not set a rule for this kind of action``."},"failure_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Detail","description":"Short failure detail as recorded."},"replaces_record":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Replaces Record","description":"The earlier record this one replaces, if any."},"replaced_by_record":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Replaced By Record","description":"The later record that replaces this one, if any."},"undoes_record":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Undoes Record","description":"The record whose action this one undid, if this is an undo."},"undone_by_record":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Undone By Record","description":"The record of the undo that reversed this action, if any."},"redactions":{"type":"integer","title":"Redactions","description":"How many secret-shaped values were removed before the record was stored. Example: ``0``.","default":0},"details":{"additionalProperties":true,"type":"object","title":"Details","description":"The stored outcome summary, as recorded."},"record_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Hash","description":"SHA-256 of the record's stored content, taken when it was recorded."},"previous_chain_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Chain Hash","description":"Chain hash of the position before this one (64 zeros for the first)."},"chain_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chain Hash","description":"SHA-256 of ``previous_chain_hash`` + ``\":\"`` + ``record_hash``. Each position commits to every position before it."}},"additionalProperties":false,"type":"object","required":["record_id","occurred_at","recorded_at","action","cause","cause_label","performed_by","performed_by_label","evidence","evidence_label","status","outcome","outcome_label"],"title":"ActionRecordExportRow","description":"One action record, as exported."},"ActionRecordLedgerHead":{"properties":{"head_sequence":{"type":"integer","title":"Head Sequence","description":"Highest sequence number issued. Example: ``42``."},"head_chain_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Head Chain Hash","description":"Chain hash at ``head_sequence``."}},"additionalProperties":false,"type":"object","required":["head_sequence"],"title":"ActionRecordLedgerHead","description":"The newest position in the app's sequence — keep it to check a later export."},"ActionRecordListResponse":{"properties":{"actions":{"items":{"$ref":"#/components/schemas/ActionRecordEntry"},"type":"array","title":"Actions","description":"The page of actions, newest first."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque cursor for the next page. Pass back verbatim as the ``cursor`` query param. ``null`` when there is no next page. Example: ``MjAyNi0wOC0xOVQwNTowMDoxMlp8MGYyYjA0…``."},"has_more":{"type":"boolean","title":"Has More","description":"True when a next page exists. Example: ``true``."}},"additionalProperties":false,"type":"object","required":["has_more"],"title":"ActionRecordListResponse","description":"Keyset-paginated list of recorded actions for one app."},"ActionRecordRetention":{"properties":{"records_kept_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Records Kept Days","description":"Days a record is kept; ``null`` means no time limit is set. Example: ``null``."},"expiry_deletion_active":{"type":"boolean","title":"Expiry Deletion Active","description":"Whether records are deleted automatically when they reach that limit. Example: ``false``."},"execution_log_kept_days":{"type":"integer","title":"Execution Log Kept Days","description":"Days Harny's separate execution logs for actions it performed are set to be kept. The records in this export do not depend on them. Example: ``30``."},"removed_when":{"items":{"type":"string"},"type":"array","title":"Removed When","description":"The events that delete records."},"statement":{"type":"string","title":"Statement","description":"The retention position in plain words."}},"additionalProperties":false,"type":"object","required":["records_kept_days","expiry_deletion_active","execution_log_kept_days","removed_when","statement"],"title":"ActionRecordRetention","description":"How long action records are kept, read from the platform's current settings."},"ActionRecordVerification":{"properties":{"gap_free":{"type":"boolean","title":"Gap Free","description":"Every position from 1 to the newest is present. A removed record keeps its position."},"chain_ok":{"type":"boolean","title":"Chain Ok","description":"Every hash agrees with its neighbour; every remaining record still matches the hash taken when it was recorded; no record is missing from the sequence."},"records_checked":{"type":"integer","title":"Records Checked","description":"Records whose content was re-checked."},"removed_records":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Removed Records","description":"Positions whose record was deleted (for example by an end user's erasure). Not reported on an end user's own export."},"anchor_ok":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Anchor Ok","description":"When ``anchor_sequence`` and ``anchor_hash`` were sent: whether the chain still has that hash at that position, i.e. nothing up to it was rewritten since."},"problems":{"items":{"$ref":"#/components/schemas/ActionRecordVerificationProblem"},"type":"array","title":"Problems","description":"What was found wrong, at most 100 entries. Not reported on an end user's own export."},"summary":{"type":"string","title":"Summary","description":"The result in plain words."}},"additionalProperties":false,"type":"object","required":["gap_free","chain_ok","records_checked","summary"],"title":"ActionRecordVerification","description":"Result of checking the app's numbered sequence and hash chain."},"ActionRecordVerificationProblem":{"properties":{"sequence":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sequence","description":"Where in the sequence."},"problem":{"type":"string","title":"Problem","description":"``missing_positions``, ``chain_break``, ``seal_mismatch``, ``record_altered``, ``ledger_tail_missing``, ``head_mismatch`` or ``record_not_in_ledger``."},"record_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Record Id","description":"The record concerned, if known."}},"additionalProperties":false,"type":"object","required":["problem"],"title":"ActionRecordVerificationProblem","description":"One thing the verification found wrong."},"ActionRecordWriteRequest":{"properties":{"target":{"type":"string","maxLength":256,"minLength":1,"title":"Target","description":"The thing the action operated on, in ``noun.verb`` or ``noun.verb.qualifier`` shape. Example: ``profile.update``."},"status":{"type":"string","enum":["processing","completed","partial","failed"],"title":"Status","description":"Outcome of the action, from the runtime's own vocabulary. One of ``processing`` | ``completed`` | ``partial`` | ``failed``. Example: ``completed``."},"parameters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Parameters","description":"The tool-call parameters the agent used, as a JSON object. Scrubbed for secrets and clamped for size before storage; put bulk behind ``artifact_ref``. Example: ``{\"user_id\": \"u_123\", \"field\": \"phone\"}``."},"outcome_summary":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Outcome Summary","description":"A small JSON object describing what became true after the action ran. Scrubbed and size-clamped like ``parameters``. Example: ``{\"rows_updated\": 1, \"new_phone_last4\": \"1234\"}``."},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code","description":"The upstream tool's own error code, as your runtime received it. Used only for structured failure classification — never text-sniffed. Example: ``rate_limited``."},"http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Http Status","description":"The upstream HTTP status code, when the action was an HTTP call. Example: ``429``."},"failure_detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Detail","description":"One short free-text sentence explaining the failure to a human. Scrubbed and clamped to 512 characters. Example: ``retry-after 30s per upstream``."},"artifact_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Artifact Ref","description":"A pointer to a large artifact the action produced (report, transcript, exported file). Kept out of ``parameters`` / ``outcome_summary`` so the row itself stays small. Example: ``s3://tenant-42/reports/2026-08-19/run-abc.pdf``."},"correlation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Correlation Id","description":"A caller-chosen id that groups the actions of one agent run together. Example: ``run_2026-08-19T05:00_agent7``."},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency Key","description":"A caller-chosen key that makes a retried report a no-op instead of a duplicate row. Unique per app. Example: ``profile.update:u_123:2026-08-19T05:00``."},"supersedes_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Supersedes Id","description":"The id of an earlier record this one replaces (a retry, a correction). Must be a record of the same app; a cross-app id is rejected. A record Harny wrote about an action it took is never marked replaced by your records. Example: ``0f2b04ee-59d3-4b6c-9c6a-8b0f7e1e9c19``."},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At","description":"When the action actually happened, in your runtime's clock. Defaults to now. A far-future value is clamped to now. Example: ``2026-08-19T05:00:12Z``."},"effect":{"anyOf":[{"type":"string","enum":["read","write","unknown"]},{"type":"null"}],"title":"Effect","description":"Coded action-effect: ``read`` | ``write`` | ``unknown``. Optional; the SDK's wrapper usually has the HTTP method in hand (``GET``/``HEAD`` → ``read``, ``POST``/``PUT``/``PATCH``/``DELETE`` → ``write``). Stored as ``unknown`` if omitted. A severity amplifier only — no signal fires because the effect is ``write``. Example: ``write``."},"initiated_by":{"anyOf":[{"type":"string","enum":["user_request","schedule","agent_plan","system_event","unknown"]},{"type":"null"}],"title":"Initiated By","description":"What caused this action to be attempted: ``user_request`` (a person asked for it), ``schedule`` (a timer or cron fired), ``agent_plan`` (the agent decided on it while pursuing an earlier goal), ``system_event`` (a webhook, callback or platform event). Optional; stored as ``unknown`` if omitted. Read it from your runtime's own execution context — do not let the model choose it, and do not derive it from ``target``. This is the only record of causation there will ever be: without it a person's request and a nightly job are the same row. Example: ``user_request``."}},"additionalProperties":false,"type":"object","required":["target","status"],"title":"ActionRecordWriteRequest","description":"One action a developer's agent took, being reported after the fact.\n\nThe subject (which end user this was about) is NEVER carried in the body.\nIt comes from the calling ``fsa_`` credential and the ``X-Harny-User``\nheader; a body carrying ``user_id`` / ``app_id`` / ``actor_type`` /\n``recorded_via`` is rejected by ``extra=\"forbid\"``."},"ActionRecordWriteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"The stored record's id. Use as ``supersedes_id`` on a follow-up. Example: ``0f2b04ee-59d3-4b6c-9c6a-8b0f7e1e9c19``."},"deduplicated":{"type":"boolean","title":"Deduplicated","description":"True when this call matched an earlier one by ``idempotency_key`` and no new row was written. Example: ``false``."},"redaction_count":{"type":"integer","title":"Redaction Count","description":"How many secret-shaped substrings the scrubber removed before storage. Example: ``0``."},"status":{"type":"string","enum":["processing","completed","partial","failed"],"title":"Status","description":"Echo of the stored status. Example: ``completed``."},"failure_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Failure Class","description":"Structured failure category derived from ``error_code`` / ``http_status``. ``null`` for successful actions. Example: ``rate_limited``."},"retry_posture":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retry Posture","description":"What an agent can do about this failure, if any. ``null`` for successes. Example: ``retry_after_fix``."},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At","description":"The action's own timestamp, possibly clamped to now. Example: ``2026-08-19T05:00:12Z``."},"recorded_at":{"type":"string","format":"date-time","title":"Recorded At","description":"When the platform recorded the row. Example: ``2026-08-19T05:00:13Z``."}},"additionalProperties":false,"type":"object","required":["id","deduplicated","redaction_count","status","occurred_at","recorded_at"],"title":"ActionRecordWriteResponse","description":"Acknowledgement of a recorded action."},"AuthProvisionRequest":{"properties":{"app_name":{"type":"string","maxLength":255,"minLength":1,"title":"App Name","description":"Human-readable name for the new application. Used in audit logs and the developer dashboard."},"contact_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Contact Email","description":"Optional. A contact address for platform messages. Leave it out when you do not have one: the app's owner gives their sign-in address when they claim the app. Not exposed to end users."},"model_preset":{"anyOf":[{"type":"string","enum":["cost_first","quality_first","regulated"]},{"type":"null"}],"title":"Model Preset","description":"Optional. The model preset chosen for this app: cost_first, quality_first or regulated. It is stored with the app now, so Harny's own processing of what the app loads follows it from the first fact (regulated keeps that processing on the allowed providers). The owner can change it after the claim."},"developer_agreement_accepted":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Developer Agreement Accepted","description":"Accepted for compatibility but ignored. Calling this endpoint constitutes acceptance of the developer agreement regardless of this field's value. The accepted version is returned in the response."},"objective":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Objective","description":"What the app does, in one or two sentences, in the business's words. Stored as the app's objective; the owner can change it."},"customers":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Customers","description":"Who the app's customers are, in one or two sentences. Stored with the app's objective; the owner can change it."},"assistant_name":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Assistant Name","description":"Optional. Your own name: the product you run as, the way you would say who you are. The app's owner sees it on their Home as who set the app up. Leave it out if you do not know it; Harny never fills it in for you."}},"additionalProperties":false,"type":"object","required":["app_name"],"title":"AuthProvisionRequest","description":"Public bootstrap request for app provisioning.\n\nCalling this endpoint constitutes acceptance of the current developer\nagreement. The ``developer_agreement_accepted`` field is accepted for\nconvenience but has no effect — the agreement is recorded automatically."},"AuthProvisionResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id","description":"Unique identifier for the newly provisioned application."},"app_api_key":{"type":"string","title":"App Api Key","description":"Full app API key (fsa_ prefix). Shown once. Use as Bearer token to provision users."},"app_api_key_display":{"type":"string","title":"App Api Key Display","description":"Truncated display form of the app API key for logging and UI display."},"developer_agreement_version":{"type":"string","title":"Developer Agreement Version","description":"Version of the developer agreement accepted during bootstrap provisioning."},"instructions":{"type":"string","title":"Instructions","description":"Human-readable onboarding instructions, including a copy-pasteable curl example for the next call. For machine consumption prefer the structured ``next_step`` field."},"next_step":{"$ref":"#/components/schemas/NextStep","description":"Machine-readable pointer to the immediate next call (POST /v1/users to mint a user key). Lets a developer's agent chain provisioning without consulting the OpenAPI."},"claim_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Claim Url","description":"one-time URL the developer opens to take ownership of this app. Not a credential; expires and is single-use. If you (agent) can open URLs, open this for the developer; otherwise show the sentence embedded in `instructions`."},"claim_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Claim Expires At","description":"UTC timestamp after which the claim URL stops working."}},"additionalProperties":false,"type":"object","required":["app_id","app_api_key","app_api_key_display","developer_agreement_version","instructions","next_step"],"title":"AuthProvisionResponse","description":"Public bootstrap response containing the initial app key and onboarding instructions.\n\n Workstream E — the response also carries a `claim_url` +\n`claim_expires_at`. The `instructions` field embeds one plain\nsentence the AI agent SHOULD relay verbatim if it cannot open the\nURL itself; agents that can open browsers SHOULD do so silently.\n"},"BlockBasis":{"type":"string","enum":["observed","stated","inferred","extracted"],"title":"BlockBasis","description":"How the knowledge in this block was obtained."},"BlockFreshness":{"type":"string","enum":["current","aging","stale"],"title":"BlockFreshness","description":"How current the underlying data is relative to its sync cadence."},"Body_ingest_file_v1_vault_ingest_file_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_ingest_file_v1_vault_ingest_file_post"},"ClaimLinkResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id","description":"App the URL will claim."},"claim_url":{"type":"string","title":"Claim Url","description":"Fresh one-time URL."},"claim_expires_at":{"type":"string","format":"date-time","title":"Claim Expires At","description":"UTC timestamp after which the claim URL stops working."},"user_message":{"type":"string","title":"User Message","description":"Plain sentence the AI agent SHOULD show verbatim if it cannot open the URL itself."}},"additionalProperties":false,"type":"object","required":["app_id","claim_url","claim_expires_at","user_message"],"title":"ClaimLinkResponse","description":"Workstream E — re-issued claim block for an existing app.\n\nReturned by `POST /v1/apps/{app_id}/claim-link` (authenticated with\nthe app's own `fsa_` key). Same shape as the `claim_*` fields on\n`AuthProvisionResponse`."},"ClaimRedeemRequest":{"properties":{"token":{"type":"string","maxLength":256,"minLength":8,"title":"Token","description":"Raw claim token from the URL's ?token= parameter."}},"additionalProperties":false,"type":"object","required":["token"],"title":"ClaimRedeemRequest","description":"Workstream E — Clerk-verified redeem body.\n\nThe signed-in Clerk user's `X-Clerk-BFF-Session` header is the\nauthenticating credential (handled by the router dependency); the\nbody carries only the raw token. Never appears in logs."},"ClaimRedeemResponse":{"properties":{"app_id":{"type":"string","format":"uuid","title":"App Id","description":"App now owned by the caller."},"app_name":{"type":"string","title":"App Name","description":"Human-readable name of the claimed app."},"dashboard_url":{"type":"string","title":"Dashboard Url","description":"Console page to open after the claim: the dashboard, with the claimed app selected."}},"additionalProperties":false,"type":"object","required":["app_id","app_name","dashboard_url"],"title":"ClaimRedeemResponse","description":"Successful ownership binding."},"ConflictAnswerRequest":{"properties":{"record_id_1":{"type":"string","maxLength":128,"minLength":1,"title":"Record Id 1","description":"The record_id_1 of the conflict, exactly as the context response gave it."},"record_id_2":{"type":"string","maxLength":128,"minLength":1,"title":"Record Id 2","description":"The record_id_2 of the conflict, exactly as the context response gave it."},"answer":{"type":"string","maxLength":10000,"minLength":1,"title":"Answer","description":"The user's answer, as a statement in their own words that stands on its own (for example 'Maya prefers email'). It is saved as something the user said."}},"additionalProperties":false,"type":"object","required":["record_id_1","record_id_2","answer"],"title":"ConflictAnswerRequest"},"ConflictAnswerResponse":{"properties":{"conflict_key":{"type":"string","title":"Conflict Key","description":"Names this conflict; the same value the context response gives."},"answered":{"type":"boolean","title":"Answered","description":"True once the answer is saved; the conflict is no longer returned."},"status":{"type":"string","title":"Status","description":"How the saving went: 'ingested', 'deduped' or 'queued'."},"message":{"type":"string","title":"Message","description":"A readable line about the saving."},"resource_uri":{"type":"string","title":"Resource Uri","description":"Identifies the saved answer."}},"additionalProperties":false,"type":"object","required":["conflict_key","answered","status","message","resource_uri"],"title":"ConflictAnswerResponse"},"ConflictAskedResponse":{"properties":{"conflict_key":{"type":"string","title":"Conflict Key","description":"Names this conflict; the same value the context response gives."},"first_time":{"type":"boolean","title":"First Time","description":"True the first time you report this conflict as asked, false on every repeat."}},"additionalProperties":false,"type":"object","required":["conflict_key","first_time"],"title":"ConflictAskedResponse"},"ConflictRef":{"properties":{"record_id_1":{"type":"string","maxLength":128,"minLength":1,"title":"Record Id 1","description":"The record_id_1 of the conflict, exactly as the context response gave it."},"record_id_2":{"type":"string","maxLength":128,"minLength":1,"title":"Record Id 2","description":"The record_id_2 of the conflict, exactly as the context response gave it."}},"additionalProperties":false,"type":"object","required":["record_id_1","record_id_2"],"title":"ConflictRef"},"ContextAssembleRequest":{"properties":{"query":{"type":"string","maxLength":2000,"minLength":1,"title":"Query","description":"Natural-language question or task that drives context retrieval and ranking."},"token_budget":{"type":"integer","maximum":128000,"minimum":256,"title":"Token Budget","description":"Maximum prompt tokens the assembled context payload may consume. Defaults to 4096 when omitted.","default":4096},"assembly_profile":{"type":"string","maxLength":64,"minLength":1,"title":"Assembly Profile","description":"Named context-shaping profile. Current supported value is `default`. Future app/agent/use-case templates extend this selector without changing the API contract.","default":"default"},"thread_id":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Thread Id","description":"Reserved opaque thread identifier for future thread-scoped context. Accepted but not acted on in."},"include_tools":{"type":"boolean","title":"Include Tools","description":"Include tool inventory blocks when available.","default":true},"source_filter":{"anyOf":[{"items":{"type":"string","enum":["vault","context_source","memory","linked","tool","permission"]},"type":"array"},{"type":"null"}],"title":"Source Filter","description":"Optional retrieval-source allowlist. When omitted, all supported sources are eligible. Supported values: vault, context_source, memory, linked, tool."},"min_relevance_score":{"anyOf":[{"type":"number","maximum":1,"minimum":0},{"type":"null"}],"title":"Min Relevance Score","description":"Optional override of the server-side minimum relevance score for context blocks. Blocks below this threshold are dropped before budget allocation. When omitted, the operator-configured default applies."},"conversation_context":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":5},{"type":"null"}],"title":"Conversation Context","description":"Last N conversation turns for context-adaptive retrieval. When provided, entities and topics extracted from these turns receive a score boost during assembly."}},"additionalProperties":false,"type":"object","required":["query"],"title":"ContextAssembleRequest","description":"Request payload for one budget-aware Smart Profiles context assembly operation.","example":{"assembly_profile":"default","include_tools":true,"query":"What do you know about my contact preferences?","source_filter":["vault","context_source","memory"],"token_budget":4096}},"ContextAssembleResponse":{"properties":{"blocks":{"items":{"$ref":"#/components/schemas/ContextBlock"},"type":"array","title":"Blocks","description":"Ranked ready-to-inject context blocks that fit within the applied token budget."},"total_tokens":{"type":"integer","minimum":0,"title":"Total Tokens","description":"Total token count across the returned blocks."},"budget_used":{"type":"integer","minimum":0,"title":"Budget Used","description":"Tokens used by the returned blocks. Usually within the token budget you requested; when a long history needs more room to keep its best evidence whole, it can be higher, up to the limit of your plan. budget_remaining is then 0."},"budget_remaining":{"type":"integer","minimum":0,"title":"Budget Remaining","description":"Unused portion of the requested token budget after assembly."},"query":{"type":"string","maxLength":2000,"minLength":1,"title":"Query","description":"Echo of the normalized query used to assemble context."},"assembly_profile":{"type":"string","maxLength":64,"minLength":1,"title":"Assembly Profile","description":"Echo of the normalized context-shaping profile used for assembly."},"sources_queried":{"items":{"type":"string","enum":["vault","context_source","memory","linked","tool"]},"type":"array","title":"Sources Queried","description":"Retrieval sources attempted for this assembly request. Supported values: vault, context_source, memory, linked, tool."},"degraded_sources":{"items":{"type":"string","enum":["vault","context_source","memory","linked","tool"]},"type":"array","title":"Degraded Sources","description":"Subset of queried sources that failed and were omitted or only partially available. Same public-name space as sources_queried."},"source_failures":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Source Failures","description":"Optional mechanical failure-class map keyed by public source name (or the synthetic 'assembly' key for early-return reasons). Absent on happy-path responses; populated when at least one source degraded or assembly skipped retrieval. Value strings come from the server's internal failure classifier and are stable enough for bench label routing but not part of the public contract (opaque to developer clients)."},"thread_id":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Thread Id","description":"Opaque thread identifier echoed back when supplied by the caller."},"query_interpretation":{"anyOf":[{"$ref":"#/components/schemas/QueryInterpretation"},{"type":"null"}],"description":"What the system understood about the query. Populated when query decomposition is active."},"request_id":{"type":"string","title":"Request Id","description":"Correlation id matching the ``X-Request-Id`` response header. When the caller supplies ``x-request-id`` it is honored end-to-end; otherwise a fresh uuid4 hex is generated by the request-observability middleware. Use this to look up the request in developer telemetry."},"issue":{"anyOf":[{"$ref":"#/components/schemas/Issue"},{"type":"null"}],"description":"Singular, mechanically-earned issue attached to a thin or empty response. Fires ONLY when the richness/blocks-count thinness gate trips AND a mechanical registry state applies (nothing_connected / syncing / source_failing / no_match). Never derived from query intent. Null on the happy path."},"capture_health":{"anyOf":[{"$ref":"#/components/schemas/EmailCaptureHealth"},{"type":"null"}],"description":"Email-capture channel health for this user, when they have an email connection (Apps Script push and/or forwarding). Absent when there is no email connection. The developer's app can relay ``status_message`` and ``action`` to the end user."},"conflicts":{"anyOf":[{"items":{"$ref":"#/components/schemas/ContextConflict"},"type":"array"},{"type":"null"}],"title":"Conflicts","description":"Two things one user said that cannot both be true, for example 'I prefer email' and, later, 'I prefer phone'. Harny keeps both and picks neither. Each item gives both statements, the day each was said, the day the first one happened, and the ids of the stored notes. Use it to show the user both and let them choose, in your own interface. When same_conversation is true, do not ask about it in that conversation. Absent when there is nothing to report."},"conflict_question_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"When notes conflict","description":"How to word the question when you ask the user about a conflict: your app's 'When notes conflict' setting (simple, precise or handoff). Absent when there is no conflict, and absent while Harny has the question switched off: then do not ask."}},"additionalProperties":false,"type":"object","required":["total_tokens","budget_used","budget_remaining","query","assembly_profile","request_id"],"title":"ContextAssembleResponse","description":"Response payload for one assembled Smart Profiles context result set.\n\n (honesty-surface v1.5): the response replaces the prior\nfive-field epistemic surface with ONE mechanically-earned ``issue``\nobject that fires only when the thinness gate + a mechanical gap\nboth apply. Happy-path responses carry no ``issue``. Every response\ncarries a ``request_id`` matching the ``X-Request-Id`` response\nheader for developer log correlation.","examples":[{"summary":"Happy path — blocks returned, no issue","value":{"assembly_profile":"default","blocks":[{"content":"User prefers morning meetings.","metadata":{"origin":"vault"},"score":0.88,"source_type":"vault","token_count":5}],"budget_remaining":4091,"budget_used":5,"degraded_sources":[],"query":"when do I like to meet?","request_id":"3fa85f6457174562b3fc2c963f66afa6","sources_queried":["vault","context_source"],"total_tokens":5}},{"summary":"Nothing connected — first-time user, no sources yet","value":{"assembly_profile":"default","blocks":[],"budget_remaining":4096,"budget_used":0,"degraded_sources":[],"issue":{"fix_url":"/console/context-sources","next":"connect","plain":"No sources connected for this user yet.","reason":"nothing_connected"},"query":"what do you know about me?","request_id":"3fa85f6457174562b3fc2c963f66afa6","sources_queried":[],"total_tokens":0}},{"summary":"Source failing — a specific provider's background sync is failing","value":{"assembly_profile":"default","blocks":[],"budget_remaining":4096,"budget_used":0,"degraded_sources":["context_source"],"issue":{"fix_url":"/console/context-sources","next":"reconnect","plain":"Source gmail has a failing sync.","reason":"source_failing","scope":"gmail"},"query":"what's in my inbox?","request_id":"3fa85f6457174562b3fc2c963f66afa6","sources_queried":["vault","context_source"],"total_tokens":0}}],"example":{"assembly_profile":"default","blocks":[{"content":"Contact preference: prefers email over phone.","metadata":{"category":"preferences","origin":"vault","resource_uri":"fs://vault/resource/res_123"},"score":0.92,"source_type":"vault","token_count":14}],"budget_remaining":4082,"budget_used":14,"degraded_sources":[],"query":"What do you know about my contact preferences?","request_id":"3fa85f6457174562b3fc2c963f66afa6","sources_queried":["vault","context_source","memory","tool"],"thread_id":"thread-123","total_tokens":14}},"ContextBlock":{"properties":{"source_type":{"type":"string","enum":["vault","context_source","linked","tool","memory"],"title":"Source Type","description":"Normalized retrieval source type for Home Context or Shared Context ranking and attribution."},"score":{"type":"number","maximum":1,"minimum":0,"title":"Score","description":"Normalized relevance score in the inclusive range [0.0, 1.0]."},"content":{"type":"string","minLength":1,"title":"Content","description":"Ready-to-inject prompt text assembled from one Home Context or Shared Context retrieval source."},"token_count":{"type":"integer","minimum":0,"title":"Token Count","description":"Token count for the ready-to-inject content using the assembly tokenizer."},"policy":{"$ref":"#/components/schemas/ContextBlockPolicy","description":"Typed policy provenance used to distinguish Home Context from Shared Context and enforce assembly gating."},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Source-specific attribution and debugging metadata. Clients may treat this as opaque."},"last_refreshed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Refreshed At","description":"UTC timestamp of the most recent data refresh for this block's source. None when the source does not track freshness."},"temporal":{"anyOf":[{"$ref":"#/components/schemas/TemporalAnchor"},{"type":"null"}],"description":"Temporal context computed at response time. Populated when query decomposition is active."},"basis":{"anyOf":[{"$ref":"#/components/schemas/BlockBasis"},{"type":"null"}],"description":"How this knowledge was obtained. 'observed' = direct from a source record (email, calendar event). 'stated' = user explicitly provided (vault push). 'inferred' = derived by LLM extraction (memory). 'extracted' = deterministic extraction (contact stats, constraints)."},"freshness":{"anyOf":[{"$ref":"#/components/schemas/BlockFreshness"},{"type":"null"}],"description":"How current the underlying data is. 'current' = source synced within its normal interval. 'aging' = source synced between 1x-3x its normal interval. 'stale' = source synced more than 3x its normal interval or sync failed."},"provenance_type":{"anyOf":[{"type":"string","enum":["user_stated","email","calendar","document","system_inferred","tool_metadata"]},{"type":"null"}],"title":"Provenance Type","description":"Content provenance category used for trust hierarchy scoring."},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Occurred At","description":"When the content event originally happened (email received, meeting started)."},"last_retrieved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Retrieved At","description":"When this block was last assembled into a retrieval result."},"confidence_tier":{"anyOf":[{"type":"string","enum":["high","medium","low"]},{"type":"null"}],"title":"Confidence Tier","description":"Graduated confidence tier assigned post-transform. Stripped at response serialization when graduated_confidence_enabled=False."},"uncertainty_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uncertainty Note","description":"Confidence caveat note. Stripped at response serialization when graduated_confidence_enabled=False."}},"additionalProperties":false,"type":"object","required":["source_type","score","content","token_count","policy"],"title":"ContextBlock","description":"Unified ready-to-inject Home Context or Shared Context block.","example":{"content":"Contact preference: prefers email over phone.","last_refreshed_at":"2026-04-20T14:37:12Z","metadata":{"category":"preferences","origin":"vault","origin_scope":"home_context","resource_uri":"fs://vault/resource/res_123"},"policy":{"consent_basis":"self_app_scope","cross_app":false,"origin_app_id":"11111111-1111-1111-1111-111111111111","sharing_tier":"restricted"},"score":0.92,"source_type":"vault","token_count":14}},"ContextBlockPolicy":{"properties":{"cross_app":{"type":"boolean","title":"Cross App","description":"Whether this block belongs to Shared Context instead of Home Context. When false, the block is Home Context from the requesting app's own scope. When true, the block is Shared Context from another app's abstracted shared-fact layer."},"sharing_tier":{"type":"string","enum":["open","sensitive","restricted"],"title":"Sharing Tier","description":"Policy sensitivity tier associated with the Home Context or Shared Context block."},"consent_basis":{"type":"string","enum":["self_app_scope","vault_link_category_policy"],"title":"Consent Basis","description":"Policy basis used to authorize this block for assembly. `self_app_scope` corresponds to Home Context. `vault_link_category_policy` corresponds to Shared Context."},"origin_app_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Origin App Id","description":"App provenance for the Home Context or Shared Context block origin."}},"additionalProperties":false,"type":"object","required":["cross_app","sharing_tier","consent_basis"],"title":"ContextBlockPolicy","description":"Typed Smart Profiles provenance attached to each assembled context block."},"ContextConflict":{"properties":{"statement_1":{"type":"string","title":"Statement 1","description":"The first thing the user said, about something that happened. Their own words when Harny has them; otherwise the note as Harny stored it."},"said_1":{"type":"string","title":"Said 1","description":"The day they said it (YYYY-MM-DD)."},"event_date_1":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Date 1","description":"The day the first statement says it happened (YYYY-MM-DD). Null when it gives no day."},"statement_2":{"type":"string","title":"Statement 2","description":"The second thing the user said. Their own words when Harny has them; otherwise the note as Harny stored it. They said it after they said the first one, and it cannot be true together with it."},"said_2":{"type":"string","title":"Said 2","description":"The day they said it (YYYY-MM-DD)."},"record_id_1":{"type":"string","title":"Record Id 1","description":"The id of the stored note behind statement_1."},"record_id_2":{"type":"string","title":"Record Id 2","description":"The id of the stored note behind statement_2."},"same_conversation":{"type":"boolean","title":"Same Conversation","description":"True when the user said both in one conversation. Do not ask them about it there; they have just said it."},"speaker":{"type":"string","title":"Speaker","description":"Who said both. Harny only pairs statements from the same user."},"conflict_key":{"type":"string","title":"Conflict Key","description":"Names this conflict. The same in every response, whichever statement is listed first."},"asked":{"type":"boolean","title":"Asked","description":"True when your app has already reported asking the user about this conflict. Ask at most once."}},"additionalProperties":false,"type":"object","required":["statement_1","said_1","statement_2","said_2","record_id_1","record_id_2","same_conversation","speaker","conflict_key","asked"],"title":"ContextConflict","description":"Two things one user said that cannot both be true.\n\nReturned in ``conflicts`` so your own interface can show them. Neither\nstatement replaces the other: nothing here says which one is right."},"ContextSourceConnectRequest":{"properties":{"return_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Return Url"},"capabilities":{"anyOf":[{"items":{"type":"string","enum":["calendar.events.write","gmail.messages.send"]},"type":"array","maxItems":4},{"type":"null"}],"title":"Capabilities","description":"Optional. Ask for more than the default read-only access, added to the end user's existing connection. calendar.events.write (on the calendar connection) lets a catalog action add or remove events on the user's own calendar; gmail.messages.send (on the gmail connection) lets the email.send action send mail from the user's own Gmail. Omit for read-only."},"shared_facts_opt_in":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Shared Facts Opt In","description":"Optional. Send true only when the end user themselves ticked Harny's question about sharing short facts with their other apps that use Harny (the widgets show it unticked). Harny saves it as the end user's own choice when the connection completes. Omit it, or send false, when they did not tick it: that records nothing and never withdraws an earlier yes. An end user flagged as a child cannot opt in."}},"type":"object","title":"ContextSourceConnectRequest","description":"Start OAuth connect flow for one provider."},"ContextSourceConnectResponse":{"properties":{"provider":{"type":"string","enum":["gmail","calendar","drive","notion","slack","email_bridge"],"title":"Provider"},"authorization_url":{"type":"string","title":"Authorization Url"},"state":{"type":"string","title":"State"},"expires_in_seconds":{"type":"integer","title":"Expires In Seconds"}},"type":"object","required":["provider","authorization_url","state","expires_in_seconds"],"title":"ContextSourceConnectResponse","description":"OAuth redirect payload for context source connection."},"ContextSourceConnectionSummary":{"properties":{"connection_id":{"type":"string","format":"uuid","title":"Connection Id"},"provider":{"type":"string","enum":["gmail","calendar","drive","notion","slack","email_bridge"],"title":"Provider"},"status":{"type":"string","enum":["connected","disconnected","error"],"title":"Status"},"connected_at":{"type":"string","format":"date-time","title":"Connected At"},"last_synced_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Synced At"},"last_sync_status":{"anyOf":[{"type":"string","enum":["idle","running","success","failed"]},{"type":"null"}],"title":"Last Sync Status"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"pending_jobs":{"type":"integer","title":"Pending Jobs","default":0}},"type":"object","required":["connection_id","provider","status","connected_at"],"title":"ContextSourceConnectionSummary","description":"One provider connection and sync status."},"ContextSourceDisconnectRequest":{"properties":{"delete_synced_data":{"type":"boolean","title":"Delete Synced Data","default":true}},"type":"object","title":"ContextSourceDisconnectRequest","description":"Disconnect options for one provider."},"ContextSourceDisconnectResponse":{"properties":{"provider":{"type":"string","enum":["gmail","calendar","drive","notion","slack","email_bridge"],"title":"Provider"},"status":{"type":"string","const":"disconnected","title":"Status"},"deleted_items":{"type":"integer","title":"Deleted Items"},"message":{"type":"string","title":"Message"}},"type":"object","required":["provider","status","deleted_items","message"],"title":"ContextSourceDisconnectResponse","description":"Provider disconnection result."},"ContextSourceListResponse":{"properties":{"sources":{"items":{"$ref":"#/components/schemas/ContextSourceConnectionSummary"},"type":"array","title":"Sources"}},"type":"object","title":"ContextSourceListResponse","description":"List of context source connections for the current user."},"ContextSourceSyncRequest":{"properties":{"full_resync":{"type":"boolean","title":"Full Resync","default":false}},"type":"object","title":"ContextSourceSyncRequest","description":"Manual sync trigger options."},"ContextSourceSyncResponse":{"properties":{"provider":{"type":"string","enum":["gmail","calendar","drive","notion","slack","email_bridge"],"title":"Provider"},"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","enum":["queued","processing","completed","failed"],"title":"Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["provider","job_id","status","message"],"title":"ContextSourceSyncResponse","description":"Manual sync enqueue response."},"DataRequestCreateRequest":{"properties":{"kind":{"type":"string","enum":["access","deletion","correction","objection","objection_withdrawal","shared_facts_withdrawal"],"title":"Kind","description":"access: a copy of the data held. deletion: erase it. correction: fix something wrong. objection: stop Harny using the data to improve the service, for statistics or to count senders (takes effect at once). objection_withdrawal: lift that objection (takes effect once Harny has checked with the end user; not accepted from the app key). shared_facts_withdrawal: turn off sharing facts with the end user's other apps (takes effect at once)."},"details":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Details","description":"What the request is about. Required for a correction: what is wrong and what is right."},"contact_email":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"title":"Contact Email","description":"Where to send the answer, when it should not go through the app."}},"type":"object","required":["kind"],"title":"DataRequestCreateRequest"},"DataRequestListResponse":{"properties":{"requests":{"items":{"$ref":"#/components/schemas/DataRequestResponse"},"type":"array","title":"Requests"}},"type":"object","required":["requests"],"title":"DataRequestListResponse"},"DataRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"kind":{"type":"string","enum":["access","deletion","correction","objection","objection_withdrawal","shared_facts_withdrawal"],"title":"Kind"},"status":{"type":"string","enum":["received","verified","in_progress","completed","rejected"],"title":"Status"},"received_at":{"type":"string","format":"date-time","title":"Received At"},"due_at":{"type":"string","format":"date-time","title":"Due At","description":"The date by which the request will be answered."},"verified_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Verified At"},"closed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Closed At"},"resolution_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolution Note"}},"type":"object","required":["id","kind","status","received_at","due_at"],"title":"DataRequestResponse"},"EmailCaptureHealth":{"properties":{"state":{"type":"string","title":"State","description":"waiting | active | paused | needs_reconnect | behind | removed"},"status_message":{"type":"string","title":"Status Message","description":"End-user, plain-language status line."},"last_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Updated At","description":"When capture last contacted the server (ISO-8601)."},"action":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action","description":"'reconnect' when the user must take action, else null."}},"additionalProperties":false,"type":"object","required":["state","status_message"],"title":"EmailCaptureHealth","description":"Plain-language email-capture health, relayed by the developer's app to\nthe end user. Rides the assemble response the app already calls, so the\n\"is my email working\" signal reaches the user where they already are\nno new screen to build or visit. Absent when the user has no email\nconnection."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HandoffCreateRequest":{"properties":{"reason":{"type":"string","maxLength":1000,"minLength":1,"title":"Reason","description":"What the agent needs a person for, in plain words. Recorded, and shown as the agent's own words; it is never the reason a person is asked (that is `because`)."},"because":{"anyOf":[{"type":"string","enum":["needs_credential","needs_signature","needs_physical_step","needs_payment_instrument","reserved_judgement","user_silent_cannot_wait","settings_forbid_no_alternative","data_conflict_unresolved"]},{"type":"null"}],"title":"Because","description":"Why a person is truly needed, as one of eight codes: needs_credential, needs_signature, needs_physical_step, needs_payment_instrument, reserved_judgement (something only a person holds); user_silent_cannot_wait (the user was asked, did not answer in time, and it cannot wait); settings_forbid_no_alternative (the settings forbid it and there is no other way); data_conflict_unresolved (the data contradicts itself and the usual ways did not settle it). The app's owner chooses how strict the door is: by default a request without it is turned back with the next step."},"tried":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":20,"title":"Tried","description":"The action records of what the agent tried before asking (from /v1/actions or an action result). Required at the default door; a request without an attempt is turned back with the next step."},"agent_name":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Agent Name","description":"Which of your agents is asking, as you name it."},"record_refs":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":20,"title":"Record Refs","description":"Action records this handoff is about (from /v1/actions or an action result)."},"idempotency_key":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Idempotency Key","description":"Send the same key on a retry and the first handoff comes back."}},"additionalProperties":false,"type":"object","required":["reason"],"title":"HandoffCreateRequest","description":"The agent asks for a person. Name the end user with ``X-Harny-User``."},"HandoffCreateResponse":{"properties":{"handoff":{"$ref":"#/components/schemas/HandoffView"},"created":{"type":"boolean","title":"Created","description":"False when an open handoff with the same key already existed."}},"additionalProperties":false,"type":"object","required":["handoff","created"],"title":"HandoffCreateResponse"},"HandoffPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/HandoffView"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"additionalProperties":false,"type":"object","required":["items"],"title":"HandoffPage"},"HandoffResolveRequest":{"properties":{"resolved_by":{"type":"string","maxLength":200,"minLength":1,"title":"Resolved By","description":"The person who resolved it, as your team knows them. Recorded."},"note":{"type":"string","maxLength":2000,"minLength":1,"title":"Note","description":"What they did. Recorded on the action record as a human step."}},"additionalProperties":false,"type":"object","required":["resolved_by","note"],"title":"HandoffResolveRequest","description":"A named person at the business resolved the handoff."},"HandoffResolveResponse":{"properties":{"handoff":{"$ref":"#/components/schemas/HandoffView"},"already_resolved":{"type":"boolean","title":"Already Resolved","default":false}},"additionalProperties":false,"type":"object","required":["handoff"],"title":"HandoffResolveResponse"},"HandoffView":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"kind":{"type":"string","enum":["agent_request","repeated_failure","account_unreachable"],"title":"Kind"},"state":{"type":"string","enum":["open","resolved"],"title":"State"},"raised_by":{"type":"string","enum":["agent","harny"],"title":"Raised By"},"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"reason_flags":{"items":{"type":"string"},"type":"array","title":"Reason Flags"},"because":{"anyOf":[{"type":"string","enum":["needs_credential","needs_signature","needs_physical_step","needs_payment_instrument","reserved_judgement","user_silent_cannot_wait","settings_forbid_no_alternative","data_conflict_unresolved"]},{"type":"null"}],"title":"Because","description":"The code the agent gave for why a person is needed; null for a free-text request."},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code","description":"The error code behind a Harny-raised handoff."},"target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target","description":"The action the handoff is about, when there is one."},"service_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Label","description":"The service behind ``target`` in plain words, when Harny knows it. Example: ``Google Calendar``."},"next_action":{"type":"string","enum":["fix_credential","fix_routing","fix_input","reconnect_source","retry","wait_upstream","raise_quota","retire_target","none"],"title":"Next Action","description":"The coded next step (operations-view vocabulary)."},"end_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"End User Id","description":"The one end user this is about; null for an app-wide fault."},"affected_end_users":{"type":"integer","title":"Affected End Users","description":"Distinct end users affected (one fault, one item)."},"occurrences":{"type":"integer","title":"Occurrences","description":"How many times the fault was seen while this handoff was open."},"record_refs":{"items":{"type":"string"},"type":"array","title":"Record Refs"},"raised_record_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Raised Record Id"},"first_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen At"},"last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"resolved_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved By Name"},"resolution_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolution Note"},"resolution_record_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Resolution Record Id","description":"The action record of the resolution (a human step)."},"decision":{"anyOf":[{"type":"string","enum":["allowed","declined","handled","expired","cleared"]},{"type":"null"}],"title":"Decision","description":"How a resolved handoff closed: handled (done) by a person at your business, or expired when nobody did it in time; cleared when a fault stopped by itself; allowed or declined on one closed before the door existed. Null while it is open, and for one resolved with a note through the resolve route."}},"additionalProperties":false,"type":"object","required":["id","kind","state","raised_by","next_action","affected_end_users","occurrences"],"title":"HandoffView","description":"One handoff, in the operations view's vocabulary."},"Issue":{"properties":{"reason":{"type":"string","enum":["nothing_connected","syncing","source_failing","retrieval_degraded","no_match","partial_match"],"title":"Reason","description":"Machine-readable reason code from the mechanical registry. One of: nothing_connected, syncing, source_failing, retrieval_degraded, no_match, partial_match."},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope","description":"Provider name when the trigger is scoped to a specific connection row (gmail / calendar / drive / notion / email_bridge). None when the issue is account-wide or request-scoped rather than tied to one row."},"plain":{"type":"string","title":"Plain","description":"Plain-English sentence describing the mechanical situation, built deterministically from the registry template."},"next":{"type":"string","title":"Next","description":"Short verb naming the developer's next action. One of: connect, wait, reconnect, retry, fallback, use."},"fix_url":{"type":"string","title":"Fix Url","description":"Console deep link where the developer resolves the issue. Server-owned; may be a relative /console path."}},"additionalProperties":false,"type":"object","required":["reason","plain","next","fix_url"],"title":"Issue","description":"Singular, mechanically-earned issue attached to a thin/empty response.\n\n- `reason` — the machine-readable trigger code from the registry.\n- `scope` — the provider name when the trigger is provider-scoped\n (a specific row is failing/syncing). None when the trigger is\n account-wide (`nothing_connected`, `no_match`).\n- `plain` — a plain-English sentence built from the registry\n template + `scope` when present. Nothing interpretive.\n- `next` — one short verb the developer should tell the user to\n take (`connect`, `wait`, `reconnect`, `fallback`).\n- `fix_url` — the console deep link where the developer resolves\n the issue. Server-owned; templates in the REGISTRY.\n\nReplaces the previous five-field epistemic surface in one object. Happy-path responses carry no issue."},"NextStep":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method for the next call, e.g. POST."},"url":{"type":"string","title":"Url","description":"Path for the next call, relative to the API base."},"auth_header_template":{"type":"string","title":"Auth Header Template","description":"Authorization header template the caller should set. Placeholders are wrapped in angle brackets, e.g. 'Authorization: Bearer <app_api_key>'."},"body_example":{"additionalProperties":true,"type":"object","title":"Body Example","description":"Example JSON body the caller can copy-paste and edit."},"purpose":{"type":"string","title":"Purpose","description":"One-line description of what this next call achieves."}},"additionalProperties":false,"type":"object","required":["method","url","auth_header_template","purpose"],"title":"NextStep","description":"Machine-readable pointer to the next API call to make after a successful response.\n\nDesigned so a developer's agent can chain the next request without consulting the OpenAPI:\nthe response carries the exact ``method``, ``url``, auth header template, and body example."},"QueryInterpretation":{"properties":{"intent":{"type":"string","title":"Intent","description":"Classified query intent: direct_recall, synthesis, aggregation, exploration, calendar_lookup, entity_lookup, action_query."},"temporal_scope":{"anyOf":[{"$ref":"#/components/schemas/TemporalScope"},{"type":"null"}],"description":"Extracted temporal window, if any."},"entities":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Entities","description":"Extracted entity references (people, organizations)."},"source_hints":{"items":{"type":"string"},"type":"array","title":"Source Hints","description":"Source providers the query implies (gmail, calendar, etc)."},"reformulated_query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reformulated Query","description":"The cleaned query sent to retrieval after stripping temporal/entity/intent tokens. Null if no reformulation occurred."}},"additionalProperties":false,"type":"object","required":["intent"],"title":"QueryInterpretation"},"SetupActingPolicy":{"properties":{"state":{"type":"string","enum":["unset","partial","set"],"title":"State"},"version":{"type":"integer","title":"Version"},"current":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Current"},"proposal":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Proposal"},"needs_business_answer":{"type":"boolean","title":"Needs Business Answer"},"effect_if_unset":{"type":"string","title":"Effect If Unset"},"effective":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Effective","description":"What applies to the agent now, per kind: the stored settings, or, while the app is in test and the owner has not decided, the proposed ones. A kind shown as null is not done."},"reasons":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Reasons","description":"The reason the assistant stored for each proposed setting, per kind; null when it stored none."},"origin":{"additionalProperties":{"type":"string","enum":["owner","learned"]},"type":"object","title":"Origin","description":"Where each stored setting came from: owner (the owner chose it) or learned (the owner tapped a line the users' answers earned). A kind with no stored setting is absent."},"learned":{"additionalProperties":{"$ref":"#/components/schemas/SetupLearnedKind"},"type":"object","title":"Learned","description":"For each kind whose setting is learned: what it rested on and what has happened under it, as counts. A learned setting is the owner's; the agent keeps doing what it does within it."},"stage":{"type":"string","enum":["test","production"],"title":"Stage","description":"The app's stage. In test, the proposed settings apply as proposed until the owner changes them; the owner confirms the settings when moving the app to production.","default":"test"}},"type":"object","required":["state","version","current","needs_business_answer","effect_if_unset"],"title":"SetupActingPolicy","description":"The business's acting policy as it stands, and what the path proposes.\n\nA proposal is stored as proposed by `harny init` and accepted by the\nowner. A kind of action left unset means the agent reads and records but\ndoes not act on it."},"SetupAction":{"properties":{"name":{"type":"string","title":"Name"},"available":{"type":"boolean","title":"Available"},"arguments_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Arguments Schema"}},"type":"object","required":["name","available"],"title":"SetupAction"},"SetupAppView":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"api_base_url":{"type":"string","title":"Api Base Url"}},"type":"object","required":["id","name","api_base_url"],"title":"SetupAppView"},"SetupBundleRequest":{"properties":{"shape":{"type":"string","maxLength":40,"minLength":1,"title":"Shape"},"description":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Description"},"sources":{"items":{"type":"string","enum":["gmail","calendar","drive","notion","slack","email_bridge"]},"type":"array","maxItems":6,"title":"Sources"},"actions":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Actions"},"surface":{"anyOf":[{"type":"string","enum":["chat_page","email","webhook_only"]},{"type":"null"}],"title":"Surface"},"email_arrival_trigger":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Arrival Trigger"},"preset":{"anyOf":[{"type":"string","enum":["cost_first","quality_first","regulated"]},{"type":"null"}],"title":"Preset"},"deploy_target":{"type":"string","enum":["cloud_run","render","docker","unspecified"],"title":"Deploy Target","default":"unspecified"}},"additionalProperties":false,"type":"object","required":["shape"],"title":"SetupBundleRequest","description":"Body of ``POST /v1/apps/{app_id}/setup-bundle``.\n\n``shape`` is ``common:<path id>`` for one of the common setup paths, or\n``developer`` for a setup described in the developer's own words plus\nselections. ``description`` is data for the coding assistant, quoted\nverbatim; it never changes what Harny enforces."},"SetupBundleResponse":{"properties":{"bundle_version":{"type":"integer","title":"Bundle Version","default":1},"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"shape":{"type":"string","enum":["common","developer"],"title":"Shape"},"readiness":{"type":"string","enum":["ready","not_ready"],"title":"Readiness"},"readiness_gaps":{"items":{"type":"string"},"type":"array","title":"Readiness Gaps"},"path":{"anyOf":[{"$ref":"#/components/schemas/SetupPathView"},{"type":"null"}]},"developer_request":{"anyOf":[{"$ref":"#/components/schemas/SetupDeveloperView"},{"type":"null"}]},"app":{"$ref":"#/components/schemas/SetupAppView"},"keys":{"$ref":"#/components/schemas/SetupKeys"},"sources":{"$ref":"#/components/schemas/SetupSources"},"acting_policy":{"$ref":"#/components/schemas/SetupActingPolicy"},"handback":{"$ref":"#/components/schemas/SetupHandback"},"actions":{"items":{"$ref":"#/components/schemas/SetupAction"},"type":"array","title":"Actions"},"model":{"$ref":"#/components/schemas/SetupModel"},"deploy":{"$ref":"#/components/schemas/SetupDeploy"},"starter":{"$ref":"#/components/schemas/SetupStarter"},"self_check":{"$ref":"#/components/schemas/SetupSelfCheck"},"agents_md_line":{"type":"string","title":"Agents Md Line"},"hosted_runtimes":{"anyOf":[{"$ref":"#/components/schemas/SetupHostedRuntimes"},{"type":"null"}]},"files":{"additionalProperties":{"type":"string"},"type":"object","title":"Files"}},"type":"object","required":["generated_at","shape","readiness","app","keys","sources","acting_policy","actions","model","deploy","starter","self_check","agents_md_line","files"],"title":"SetupBundleResponse","description":"Everything a coding assistant needs to stand the business's agent up.\n\n``files`` holds the same content rendered as files: ``prompt.md`` (the\ninstructions), ``SKILL.md`` (an installable agent skill), the starter's\n``harny.agent.yaml``, a ``.env.example`` with variable names only, and the\ncoding-assistant settings that keep the secret file closed (one file per\nmainstream coding assistant, placed at the project root)."},"SetupBusinessToolNeed":{"properties":{"slot":{"type":"string","title":"Slot","description":"helpdesk, slack or notion."},"providers":{"items":{"type":"string"},"type":"array","title":"Providers","description":"The tools this slot accepts."},"actions":{"items":{"type":"string"},"type":"array","title":"Actions","description":"The actions of this setup that run on it."},"connected_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connected Provider","description":"The tool connected now; null when none."},"connect_endpoint":{"type":"string","title":"Connect Endpoint"}},"type":"object","required":["slot","providers","actions","connect_endpoint"],"title":"SetupBusinessToolNeed","description":"One of the business's OWN tools an action of this setup runs on.\n\nConnected once per app by the business (not per end user), with the\ncredential that tool issued; the agent never chooses the account."},"SetupDeploy":{"properties":{"target":{"type":"string","enum":["cloud_run","render","docker","unspecified"],"title":"Target"},"recipes":{"items":{"$ref":"#/components/schemas/SetupDeployRecipe"},"type":"array","title":"Recipes"},"scheduler_recipe":{"type":"string","title":"Scheduler Recipe"}},"type":"object","required":["target","recipes","scheduler_recipe"],"title":"SetupDeploy"},"SetupDeployRecipe":{"properties":{"id":{"type":"string","enum":["cloud_run","render","docker"],"title":"Id"},"name":{"type":"string","title":"Name"},"file":{"type":"string","title":"File"},"why":{"type":"string","title":"Why"}},"type":"object","required":["id","name","file","why"],"title":"SetupDeployRecipe"},"SetupDeveloperView":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"sources":{"items":{"type":"string"},"type":"array","title":"Sources"},"actions":{"items":{"type":"string"},"type":"array","title":"Actions"},"surface":{"type":"string","title":"Surface"},"email_arrival_trigger":{"type":"boolean","title":"Email Arrival Trigger"}},"type":"object","required":["description","sources","actions","surface","email_arrival_trigger"],"title":"SetupDeveloperView"},"SetupEarlyAccess":{"properties":{"status":{"type":"string","title":"Status"},"gated_providers":{"items":{"type":"string"},"type":"array","title":"Gated Providers"},"request_endpoint":{"type":"string","title":"Request Endpoint"}},"type":"object","required":["status","gated_providers","request_endpoint"],"title":"SetupEarlyAccess"},"SetupEnvVar":{"properties":{"name":{"type":"string","title":"Name"},"purpose":{"type":"string","title":"Purpose"},"secret":{"type":"boolean","title":"Secret"},"required":{"type":"boolean","title":"Required"},"where_to_get":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Where To Get"}},"type":"object","required":["name","purpose","secret","required"],"title":"SetupEnvVar"},"SetupHandback":{"properties":{"open_items":{"items":{"$ref":"#/components/schemas/SetupHandbackItem"},"type":"array","title":"Open Items"},"latest_report":{"anyOf":[{"$ref":"#/components/schemas/SetupHandbackReport"},{"type":"null"}]}},"type":"object","title":"SetupHandback","description":"What the owner handed to the coding assistant and what the assistant reported back."},"SetupHandbackItem":{"properties":{"id":{"type":"integer","title":"Id","description":"The number to give `harny done` when the request is done."},"kind":{"type":"string","enum":["owner_request","stage_changed","agent_fault"],"title":"Kind"},"text":{"type":"string","title":"Text","description":"The owner's words, Harny's note of a stage move, or (agent_fault) Harny's own note of a fault in the agent or its set-up, with the next step named: one line, quoted data."},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","kind","text","created_at"],"title":"SetupHandbackItem"},"SetupHandbackReport":{"properties":{"where":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Where"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"reported_at":{"type":"string","format":"date-time","title":"Reported At"},"label":{"type":"string","title":"Label","description":"Says the report is the assistant's word; Harny cannot check a deployment."}},"type":"object","required":["reported_at","label"],"title":"SetupHandbackReport"},"SetupHostedRuntimes":{"properties":{"mcp_url":{"type":"string","title":"Mcp Url"},"mint_endpoint":{"type":"string","title":"Mint Endpoint"},"token_default_ttl_seconds":{"type":"integer","title":"Token Default Ttl Seconds"},"how_it_works":{"items":{"type":"string"},"type":"array","title":"How It Works"},"recipes":{"items":{"$ref":"#/components/schemas/SetupRuntimeRecipe"},"type":"array","title":"Recipes"}},"type":"object","required":["mcp_url","mint_endpoint","token_default_ttl_seconds","how_it_works","recipes"],"title":"SetupHostedRuntimes","description":"For a business whose agent runs on a hosted agent runtime instead of the starter.\n\nThe business's backend mints a short-lived token per end user with the app\nkey and gives it to the runtime's MCP connection; the runtime then reads\nthat person's context and acts for that person only, through the acting\npolicy."},"SetupKeys":{"properties":{"env":{"items":{"$ref":"#/components/schemas/SetupEnvVar"},"type":"array","title":"Env"},"rules":{"items":{"type":"string"},"type":"array","title":"Rules"}},"type":"object","required":["env","rules"],"title":"SetupKeys","description":"Key handling. Names and rules only — a bundle never carries a key value."},"SetupLearnedKind":{"properties":{"mode":{"type":"string","title":"Mode","description":"The mode in force for this kind."},"set_at":{"type":"string","format":"date-time","title":"Set At","description":"When the owner applied it."},"yes_in_a_row":{"type":"integer","title":"Yes In A Row","description":"Users said yes in the app, unchanged, this many times in a row when it was applied."},"users":{"type":"integer","title":"Users","description":"From this many different users."},"done_under":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Done Under","description":"Actions the agent has done on its own under it so far."},"taken_back":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Taken Back","description":"Of those, how many users took back; null when Harny cannot see take-backs (sent mail)."},"source":{"anyOf":[{"type":"string","const":"answers"},{"type":"null"}],"title":"Source","description":"What the owner's tap rested on: ``answers`` (users said yes in the app)."},"applied_via":{"anyOf":[{"type":"string","enum":["console","api","app_key","mcp","operator"]},{"type":"null"}],"title":"Applied Via","description":"How the owner's tap reached Harny: ``console`` (signed in to the console), ``api`` (the owner's own key), or another door. Null when it is not known."},"asks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Asks","description":"How many asks the change freed: the asks it would have shown a card for, in the window it rested on."},"answered":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Answered","description":"Of those asks, how many users answered."}},"type":"object","required":["mode","set_at","yes_in_a_row","users"],"title":"SetupLearnedKind","description":"One kind whose setting is in force because the owner tapped a line the users' answers earned (counts only)."},"SetupModel":{"properties":{"preset":{"anyOf":[{"type":"string","enum":["cost_first","quality_first","regulated"]},{"type":"null"}],"title":"Preset"},"choices":{"items":{"$ref":"#/components/schemas/SetupPresetChoice"},"type":"array","title":"Choices"},"roster_endpoint":{"type":"string","title":"Roster Endpoint"},"roster_version":{"type":"string","title":"Roster Version"},"key_rule":{"type":"string","title":"Key Rule"}},"type":"object","required":["preset","choices","roster_endpoint","roster_version","key_rule"],"title":"SetupModel"},"SetupPathView":{"properties":{"id":{"type":"string","title":"Id"},"status":{"type":"string","title":"Status"},"name":{"type":"string","title":"Name"},"summary":{"type":"string","title":"Summary"},"audience":{"type":"string","title":"Audience"},"surface":{"type":"string","title":"Surface"},"first_request_example":{"type":"string","title":"First Request Example"},"later_actions":{"items":{"type":"string"},"type":"array","title":"Later Actions"}},"type":"object","required":["id","status","name","summary","audience","surface","first_request_example"],"title":"SetupPathView"},"SetupPresetChoice":{"properties":{"name":{"type":"string","enum":["cost_first","quality_first","regulated"],"title":"Name"},"description":{"type":"string","title":"Description"}},"type":"object","required":["name","description"],"title":"SetupPresetChoice"},"SetupRuntimeRecipe":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["untested","tested_locally","tested_live"],"title":"Status","description":"untested: a configuration shape from the runtime provider's documentation that has not been run end to end against that runtime."},"snippet_language":{"type":"string","enum":["json","python","typescript"],"title":"Snippet Language"},"snippet":{"type":"string","title":"Snippet"},"notes":{"items":{"type":"string"},"type":"array","title":"Notes"}},"type":"object","required":["id","name","status","snippet_language","snippet"],"title":"SetupRuntimeRecipe","description":"How one hosted agent runtime would connect to the MCP endpoint (a config shape only)."},"SetupSelfCheck":{"properties":{"commands":{"items":{"type":"string"},"type":"array","title":"Commands"},"success_means":{"items":{"type":"string"},"type":"array","title":"Success Means"}},"type":"object","required":["commands","success_means"],"title":"SetupSelfCheck"},"SetupSourceNeed":{"properties":{"provider":{"type":"string","title":"Provider"},"use":{"type":"string","enum":["read","read_write"],"title":"Use"},"capabilities":{"items":{"type":"string"},"type":"array","title":"Capabilities"},"gated":{"type":"boolean","title":"Gated","description":"Behind the platform's Google early-access approval."},"users_connected":{"type":"integer","title":"Users Connected","default":0},"users_with_write":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Users With Write"},"connect_endpoint":{"type":"string","title":"Connect Endpoint"}},"type":"object","required":["provider","use","gated","connect_endpoint"],"title":"SetupSourceNeed"},"SetupSources":{"properties":{"needed":{"items":{"$ref":"#/components/schemas/SetupSourceNeed"},"type":"array","title":"Needed"},"google_early_access":{"$ref":"#/components/schemas/SetupEarlyAccess"},"business_tools":{"items":{"$ref":"#/components/schemas/SetupBusinessToolNeed"},"type":"array","title":"Business Tools"}},"type":"object","required":["needed","google_early_access"],"title":"SetupSources"},"SetupStarter":{"properties":{"package":{"type":"string","title":"Package"},"version":{"type":"string","title":"Version"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"sdk_requirement":{"type":"string","title":"Sdk Requirement"},"config_file":{"type":"string","title":"Config File"},"lock_file":{"type":"string","title":"Lock File"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"env_names":{"items":{"type":"string"},"type":"array","title":"Env Names"}},"type":"object","required":["package","version","source","sdk_requirement","config_file","lock_file","config","env_names"],"title":"SetupStarter"},"SuppressionRuleRequest":{"properties":{"rule_type":{"type":"string","enum":["entity","topic","content"],"title":"Rule Type"},"pattern":{"type":"string","maxLength":1000,"minLength":1,"title":"Pattern"},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id"},"source":{"type":"string","enum":["user_correction","llm_feedback"],"title":"Source","default":"user_correction"}},"type":"object","required":["rule_type","pattern"],"title":"SuppressionRuleRequest"},"SuppressionRuleResponse":{"properties":{"id":{"type":"string","title":"Id"},"rule_type":{"type":"string","title":"Rule Type"},"pattern":{"type":"string","title":"Pattern"},"block_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Block Id"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"source":{"type":"string","title":"Source"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","rule_type","pattern","block_id","expires_at","source","created_at"],"title":"SuppressionRuleResponse"},"TemporalAnchor":{"properties":{"event_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Event Time","description":"When this content originated (email sent, event occurred, document edited)."},"recency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recency","description":"Human-readable relative time computed at response time."},"temporal_relevance":{"type":"string","enum":["within_scope","outside_scope","no_scope"],"title":"Temporal Relevance","description":"Whether this block falls inside the temporal scope extracted from the query.","default":"no_scope"}},"additionalProperties":false,"type":"object","title":"TemporalAnchor"},"TemporalScope":{"properties":{"start":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Start","description":"Start of the extracted temporal window."},"end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"End","description":"End of the extracted temporal window."},"label":{"type":"string","title":"Label","description":"Human-readable label for the temporal scope."}},"additionalProperties":false,"type":"object","required":["label"],"title":"TemporalScope"},"UserCreateRequest":{"properties":{"identifier":{"type":"string","maxLength":512,"title":"Identifier"},"app_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"App Id"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"email_verified":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Verified"},"email_trust_level":{"anyOf":[{"type":"string","enum":["unverified","app_asserted"]},{"type":"null"}],"title":"Email Trust Level"},"identifier_type":{"type":"string","enum":["email","app_id","device_id"],"title":"Identifier Type","default":"app_id"},"device_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Id"},"as_owner":{"type":"boolean","title":"As Owner","description":"Make this user the app's owner. Accepted only with the app's own key, when creating a new person, for an app that has no owner and no claim link, and only for the person whose email was given when the app was created. An app made by the keyless setup call gets its owner from its claim link instead. If the answer was lost, call again within a few minutes with the same values: you get a fresh key, unless the first key was already confirmed or used. Leave unset for end users.","default":false},"role":{"anyOf":[{"type":"string","enum":["staff","test"]},{"type":"null"}],"title":"Role","description":"Optional: mark the person. ``staff`` is someone who works for the business; ``test`` is an account made to try the app. Leave it out for an ordinary customer. When Harny reads how your users answer, a ``test`` account is not counted as a customer and a ``staff`` account's yes does not count toward actions that cannot be taken back. Sent again for a person who already exists, it updates the mark; leaving it out never removes one; sending ``null`` removes it. Example: ``test``."}},"type":"object","required":["identifier"],"title":"UserCreateRequest","description":"Request payload for user creation."},"UserCreateResponse":{"properties":{"user":{"$ref":"#/components/schemas/UserResponse"},"api_key_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Api Key Id"},"api_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key"},"api_key_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Key Display"},"trust_upgraded":{"type":"boolean","title":"Trust Upgraded"},"message":{"type":"string","title":"Message"},"delivery_ack_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Ack Token"},"delivery_reread_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivery Reread Expires At"}},"type":"object","required":["user","api_key_id","api_key","api_key_display","trust_upgraded","message"],"title":"UserCreateResponse","description":"Response for POST /users."},"UserDataEraseResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"status":{"type":"string","title":"Status"},"requested_at":{"type":"string","format":"date-time","title":"Requested At"},"deadline_at":{"type":"string","format":"date-time","title":"Deadline At"},"erasure_job_id":{"type":"string","format":"uuid","title":"Erasure Job Id"},"message":{"type":"string","title":"Message"}},"type":"object","required":["user_id","status","requested_at","deadline_at","erasure_job_id","message"],"title":"UserDataEraseResponse","description":"Response payload for C12 user-data erasure request."},"UserDataEraseStatusResponse":{"properties":{"user_id":{"type":"string","format":"uuid","title":"User Id"},"status":{"type":"string","enum":["pending","processing","completed","dead_letter"],"title":"Status"},"requested_at":{"type":"string","format":"date-time","title":"Requested At"},"deadline_at":{"type":"string","format":"date-time","title":"Deadline At"},"erasure_job_id":{"type":"string","format":"uuid","title":"Erasure Job Id"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"retrying":{"type":"boolean","title":"Retrying","description":"True while the job is pending/processing after at least one failed attempt. Lets the console distinguish 'queued fresh' from 'hit a temporary problem, retrying automatically'.","default":false}},"type":"object","required":["user_id","status","requested_at","deadline_at","erasure_job_id","updated_at"],"title":"UserDataEraseStatusResponse","description":"Response payload for GET /users/me/erasure-status.\n\nMirrors the persistent erasure job row so a user who triggered erasure\ncan re-read its state without re-authenticating or re-invoking DELETE."},"UserResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_id":{"type":"string","format":"uuid","title":"App Id"},"identifier":{"type":"string","title":"Identifier"},"identifier_type":{"type":"string","enum":["email","app_id","device_id"],"title":"Identifier Type"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Email"},"email_trust_level":{"type":"string","enum":["unverified","app_asserted","platform_verified"],"title":"Email Trust Level"},"identity_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity Provider"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"vault_initialized":{"type":"boolean","title":"Vault Initialized"}},"type":"object","required":["id","app_id","identifier","identifier_type","email","email_trust_level","identity_provider","created_at","vault_initialized"],"title":"UserResponse","description":"Response payload for user metadata."},"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"},"VaultBrowseEntry":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","title":"Type","description":"'directory' or 'file'"},"path":{"type":"string","title":"Path"},"uri":{"type":"string","title":"Uri"},"item_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Item Count","description":"For directory entries: number of items inside, so the UI can show a count without a drill-down. None for files/memories."}},"type":"object","required":["name","type","path","uri"],"title":"VaultBrowseEntry","description":"Single entry in a vault directory listing."},"VaultBrowseResponse":{"properties":{"path":{"type":"string","title":"Path"},"entries":{"items":{"$ref":"#/components/schemas/VaultBrowseEntry"},"type":"array","title":"Entries"}},"type":"object","required":["path"],"title":"VaultBrowseResponse","description":"Response for vault browse."},"VaultContextBlock":{"properties":{"summary":{"type":"string","title":"Summary","description":"L0 abstract — always present"},"overview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Overview","description":"L1 overview — included if score >= 0.7"},"source":{"additionalProperties":true,"type":"object","title":"Source","description":"Source metadata (type, origin)"},"path":{"type":"string","title":"Path","description":"Vault-relative path to this resource","default":""}},"type":"object","required":["summary"],"title":"VaultContextBlock","description":"Normalized context block within a vault search result."},"VaultIngestRequest":{"properties":{"source":{"type":"string","maxLength":2048,"minLength":1,"title":"Source","description":"HTTPS URL to ingest"}},"type":"object","required":["source"],"title":"VaultIngestRequest","description":"Request payload for ingesting a source URL into the user's vault."},"VaultIngestResponse":{"properties":{"status":{"type":"string","enum":["ingested","deduped","queued"],"title":"Status"},"message":{"type":"string","title":"Message"},"resource_uri":{"type":"string","minLength":1,"title":"Resource Uri"},"queued_reason":{"anyOf":[{"type":"string","enum":["extraction_unavailable","memory_service_degraded","circuit_open","empty_extraction_suspected"]},{"type":"null"}],"title":"Queued Reason","description":"Present only when status is 'queued'. Why the content was accepted for retry instead of processed inside this request: 'extraction_unavailable' (the fact-extraction step could not run), 'memory_service_degraded' (a memory backend call failed), 'circuit_open' (a backend is in sustained failure), or 'empty_extraction_suspected' (processing produced nothing and will be re-run). Poll GET /v1/vault/ingest/status with resource_uri to confirm it landed."},"existing_memory_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Existing Memory Ids","description":"Present only when status is 'deduped'. Lists memory IDs already in the vault that the dedup check ran against. Query these via GET /v1/vault/read/{id} to verify the dedup decision."}},"type":"object","required":["status","message","resource_uri"],"title":"VaultIngestResponse","description":"Response for vault ingestion."},"VaultIngestStatusResponse":{"properties":{"resource_uri":{"type":"string","title":"Resource Uri"},"status":{"type":"string","enum":["processing","completed","completed_empty","not_found","failed"],"title":"Status"},"ready":{"type":"boolean","title":"Ready"},"message":{"type":"string","title":"Message"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code"},"recovery_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recovery Hint"}},"type":"object","required":["resource_uri","status","ready","message"],"title":"VaultIngestStatusResponse","description":"Polling status for an accepted ingestion request."},"VaultPushIngestItem":{"properties":{"content":{"type":"string","maxLength":50000,"minLength":1,"title":"Content","description":"Extracted text content"},"source_id":{"type":"string","maxLength":512,"title":"Source Id","description":"Source-specific ID for dedup (e.g., Gmail message ID)","default":""},"title":{"type":"string","maxLength":500,"title":"Title","description":"Title or subject line","default":""},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Source-specific metadata (sender, date, etc.)"}},"type":"object","required":["content"],"title":"VaultPushIngestItem","description":"Single pre-extracted context item from an external source (e.g., Apps Script)."},"VaultPushIngestRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/VaultPushIngestItem"},"type":"array","maxItems":50,"minItems":0,"title":"Items"},"source_type":{"type":"string","maxLength":100,"title":"Source Type","default":"apps_script_gmail"},"expected_interval_seconds":{"anyOf":[{"type":"integer","maximum":86400,"minimum":3600},{"type":"null"}],"title":"Expected Interval Seconds","description":"Declared capture cadence (the trigger interval, in seconds). Lets the server tell an idle mailbox from a stopped one; omitted = cadence unknown."}},"type":"object","required":["items"],"title":"VaultPushIngestRequest","description":"Batch of pre-extracted context items pushed from an external source."},"VaultPushIngestResponse":{"properties":{"accepted":{"type":"integer","title":"Accepted","description":"Number of items successfully ingested"},"skipped":{"type":"integer","title":"Skipped","description":"Number of items skipped (dedup, empty)"},"failed":{"type":"integer","title":"Failed","description":"Number of items that failed (circuit breaker, etc.)"},"resource_uris":{"items":{"type":"string"},"type":"array","title":"Resource Uris","description":"URIs for accepted items"}},"type":"object","required":["accepted","skipped","failed"],"title":"VaultPushIngestResponse","description":"Response for push-ingest batch."},"VaultQueryDiagnostic":{"properties":{"hint":{"type":"string","title":"Hint","description":"Human-readable suggestion for what to check next."}},"type":"object","required":["hint"],"title":"VaultQueryDiagnostic","description":"Diagnostic info included when a vault query returns zero results."},"VaultQueryRequest":{"properties":{"query":{"type":"string","maxLength":2000,"minLength":1,"title":"Query","description":"Natural language search query"},"limit":{"type":"integer","maximum":50,"minimum":1,"title":"Limit","description":"Max results to return","default":10}},"type":"object","required":["query"],"title":"VaultQueryRequest","description":"Request payload for semantic vault search."},"VaultQueryResponse":{"properties":{"results":{"items":{"$ref":"#/components/schemas/VaultSearchResult"},"type":"array","title":"Results"},"query":{"type":"string","title":"Query","description":"Echo of the natural-language context query."},"total":{"type":"integer","title":"Total","default":0},"truncated":{"type":"boolean","title":"Truncated","default":false},"degraded_sources":{"items":{"type":"string"},"type":"array","title":"Degraded Sources"},"diagnostic":{"anyOf":[{"$ref":"#/components/schemas/VaultQueryDiagnostic"},{"type":"null"}],"description":"Present only when results are empty — hints at why and what to check."}},"type":"object","required":["query"],"title":"VaultQueryResponse","description":"Normalized response for vault queries that return context only."},"VaultReadResponse":{"properties":{"path":{"type":"string","title":"Path"},"uri":{"type":"string","title":"Uri"},"level":{"type":"string","title":"Level","description":"Requested context level: l0/l1/l2"},"content":{"type":"string","title":"Content"},"content_type":{"type":"string","title":"Content Type","default":"text/plain"}},"type":"object","required":["path","uri","level","content"],"title":"VaultReadResponse","description":"Response for reading a specific vault resource."},"VaultSearchResult":{"properties":{"id":{"type":"string","title":"Id","description":"Resource identifier (prefixed with res_)"},"score":{"type":"number","title":"Score","description":"Relevance score 0.0–1.0"},"relevance":{"type":"string","title":"Relevance","description":"Human-readable relevance: high/medium/low"},"context":{"$ref":"#/components/schemas/VaultContextBlock"}},"additionalProperties":false,"type":"object","required":["id","score","relevance","context"],"title":"VaultSearchResult","description":"Single normalized search result."},"VaultTextPasteRequest":{"properties":{"content":{"type":"string","maxLength":500000,"minLength":1,"title":"Content","description":"Raw text content to ingest. Also accepts 'text' as an alias for backward-compatible clients."},"title":{"type":"string","maxLength":200,"title":"Title","description":"Optional label for this content","default":""},"written_by_person":{"type":"boolean","title":"Written By Person","description":"Set only when the text is the end user's own typed words, never pasted, received or model-written content, and only from your backend with your app key and X-Harny-User. An email address in such text then counts as one the end user gave: after your agent read someone else's content, an invitation or message to it follows your acting settings instead of waiting for their yes. Ignored with the end user's own key. Only the addresses are kept for this, never the words.","default":false}},"type":"object","required":["content"],"title":"VaultTextPasteRequest","description":"Request payload for ingesting pasted text content."},"ErrorEnvelope":{"additionalProperties":true,"description":"Structured REST error envelope.\n\nEvery error response under `/v1` carries these fields at the top level,\nwhatever the status code. Parse `error_code` — it is the stable machine\nkey, catalogued at `/docs/errors`; `message` and `recovery_hint` are\nprose and may be reworded. Responses documented individually as\n`HTTPValidationError` carry these fields too; that schema describes the\n`detail` payload only.\n\nSome endpoints add their own context keys alongside these (a quota\nceiling, the app id the limit applied to), so the object\nis open rather than closed — read the fields you know and ignore the rest.","properties":{"error_code":{"title":"Error Code","type":"string"},"message":{"title":"Message","type":"string"},"recovery_hint":{"title":"Recovery Hint","type":"string"},"docs_url":{"title":"Docs Url","type":"string"},"retry_after_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Retry After S"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Request Id"},"detail":{"default":null,"description":"Legacy error payload, still present on every /v1 error response. A string, a list of field errors on a validation failure, or the endpoint's own object.","title":"Detail"}},"required":["error_code","message","recovery_hint","docs_url"],"title":"ErrorEnvelope","type":"object"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"fsk_<token>","description":"Harny API key as a Bearer token. Use an `fsk_` user key for user-scoped routes (OAuth, context assembly, profile reads), or an `fsa_` app key for the bootstrap routes that mint users."}}},"security":[{"bearerAuth":[]}],"servers":[{"url":"https://api.harny.ai","description":"Harny API"}]}
