{"components":{"headers":{"RateLimit":{"description":"What is left of that budget, as \"policy\";r=remaining;t=seconds until the window resets.","example":"\"default\";r=119;t=42","schema":{"type":"string"}},"RateLimitPolicy":{"description":"The budget this request counted against, as \"policy\";q=requests;w=window seconds. Each client address has 120 requests per 60 seconds, shared by the health check and the API.","example":"\"default\";q=120;w=60","schema":{"type":"string"}},"RetryAfter":{"description":"Seconds to wait before the window resets.","schema":{"minimum":1,"type":"integer"}}},"parameters":{"ExpectedSubject":{"description":"If supplied, must exactly match the verified account subject. It never selects another account.","in":"header","name":"X-Privy-User-Id","required":false,"schema":{"type":"string"}}},"schemas":{"Error":{"properties":{"error":{"properties":{"code":{"description":"A stable machine-readable code. Profile answers use the codes in examples; any other error uses its status name in snake case, such as not_found or too_many_requests.","examples":["authentication_required","profile_unconfigured","profile_unavailable","profile_not_created","profile_forbidden","invalid_profile_update","invalid_profile_json","profile_request_too_large","json_required","identity_evidence_conflict","method_not_allowed","not_found","too_many_requests","internal_server_error"],"type":"string"},"hint":{"description":"What to do next.","type":"string"},"message":{"description":"What went wrong, in words.","type":"string"}},"required":["code"],"type":"object"}},"required":["error"],"type":"object"},"Profile":{"properties":{"display_name":{"maxLength":80,"type":["string","null"]},"evidence_issued_at":{"format":"date-time","type":["string","null"]},"linked_wallets":{"items":{"pattern":"^0x[a-fA-F0-9]{40}$","type":"string"},"type":"array"},"profile_id":{"type":"string"},"verification_basis":{"const":"last_synchronized_privy_proof","type":"string"},"wallet":{"properties":{"address":{"pattern":"^0x[a-fA-F0-9]{40}$","type":["string","null"]},"verified":{"description":"True when the selected wallet is one of the linked wallets.","type":"boolean"}},"required":["address","verified"],"type":"object"},"x":{"properties":{"display_name":{"type":["string","null"]},"source":{"const":"privy","type":"string"},"username":{"type":["string","null"]},"verified":{"const":true,"type":"boolean"}},"required":["username","display_name","verified","source"],"type":["object","null"]}},"required":["profile_id","verification_basis","evidence_issued_at","display_name","linked_wallets","wallet","x"],"type":"object"},"ProfileEnvelope":{"properties":{"profile":{"$ref":"#/components/schemas/Profile"}},"required":["profile"],"type":"object"},"ProfileUpdate":{"additionalProperties":false,"minProperties":1,"properties":{"display_name":{"maxLength":80,"type":["string","null"]},"wallet_address":{"pattern":"^0x[a-fA-F0-9]{40}$","type":["string","null"]}},"type":"object"}},"securitySchemes":{"PrivyAccessToken":{"bearerFormat":"JWT","description":"Privy access token for the requesting account.","scheme":"bearer","type":"http"},"PrivyIdentityToken":{"description":"Privy identity JWT, required alongside the access token. Not an API key.","in":"header","name":"Privy-Id-Token","type":"apiKey"}}},"externalDocs":{"description":"Developer documentation: errors, rate limits, and the versioning and deprecation policy","url":"https://template.regents.sh/docs"},"info":{"contact":{"name":"Ash Template","url":"https://template.regents.sh/contact"},"description":"Service health and the signed-in person's own profile. Does not describe browser session changes. A breaking change ships with a new major info.version and is listed in the developer documentation's versioning and deprecation section the same day.","termsOfService":"https://template.regents.sh/terms","title":"Ash Template public API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/v1/profile":{"get":{"description":"Returns the profile that belongs to the presented Privy credentials. Responses use Cache-Control: no-store.","operationId":"getMyProfile","parameters":[{"$ref":"#/components/parameters/ExpectedSubject"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileEnvelope"}}},"description":"The verified account's profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Both Privy credentials were not present and valid","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The credentials do not own this profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The profile has not been created yet; call POST /api/v1/profile/sync","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Too many requests from this client address in the current window","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Sign-in is not configured or the profile service is unavailable","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Any other error, such as an unknown address or method"}},"security":[{"PrivyAccessToken":[],"PrivyIdentityToken":[]}],"summary":"Read the profile of the verified account"},"patch":{"description":"Changes the display name or the selected wallet. The body is JSON with at least one of the two fields and nothing else.","operationId":"updateMyProfile","parameters":[{"$ref":"#/components/parameters/ExpectedSubject"},{"description":"If supplied, must match the id of the profile being updated.","in":"header","name":"X-Regent-Profile-Id","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileEnvelope"}}},"description":"The updated profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The body is not valid JSON","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Both Privy credentials were not present and valid","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The credentials do not own this profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The body is larger than 8192 bytes","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"415":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The body is not application/json","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The update is invalid or the profile has not been created yet","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Too many requests from this client address in the current window","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Sign-in is not configured or the profile service is unavailable","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Any other error, such as an unknown address or method"}},"security":[{"PrivyAccessToken":[],"PrivyIdentityToken":[]}],"summary":"Update the profile of the verified account"}},"/api/v1/profile/sync":{"post":{"description":"Creates the profile on first use and refreshes it from the presented sign-in evidence afterwards.","operationId":"syncMyProfile","parameters":[{"$ref":"#/components/parameters/ExpectedSubject"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileEnvelope"}}},"description":"The current profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Both Privy credentials were not present and valid","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The credentials do not own this profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The presented evidence conflicts with the stored profile","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Too many requests from this client address in the current window","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Sign-in is not configured or the profile service is unavailable","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Any other error, such as an unknown address or method"}},"security":[{"PrivyAccessToken":[],"PrivyIdentityToken":[]}],"summary":"Create or refresh the profile of the verified account"}},"/healthz":{"get":{"description":"Returns ok when the web service is responding and its database answers; 503 unavailable otherwise. Does not establish readiness of every outside service.","operationId":"getServiceHealth","responses":{"200":{"content":{"text/plain":{"schema":{"const":"ok","type":"string"}}},"description":"Web service is responding","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Too many requests from this client address in the current window","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}}},"503":{"content":{"text/plain":{"schema":{"const":"unavailable","type":"string"}}},"description":"The web service is up but its database is not answering","headers":{"RateLimit":{"$ref":"#/components/headers/RateLimit"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"}}},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Any other error, such as an unknown address or method"}},"summary":"Read web-service health"}}},"security":[],"servers":[{"url":"https://template.regents.sh"}]}