{"openapi":"3.1.0","info":{"title":"O1 Circle application API","version":"2026-10-21","description":"Applications for O-1 and EB-1 community membership. Agents must act on the applicant’s instructions, obtain consent, and treat application access codes and documents as private. Membership approval and evidence review are owner-only operations, not part of this public API.","contact":{"email":"members@o1circle.com"}},"servers":[{"url":"https://o1circle.com"}],"externalDocs":{"description":"Agent workflow, consent and privacy requirements","url":"https://o1circle.com/agent-guide"},"components":{"securitySchemes":{"ApplicationCode":{"type":"http","scheme":"bearer","description":"Private 64-character application access code. Never put this in a URL."},"ApplicationCookie":{"type":"apiKey","in":"cookie","name":"__Host-o1_application","description":"Application cookie issued after creation or code exchange."}},"schemas":{"ApplicationInput":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":2,"maxLength":100},"email":{"type":"string","format":"email","maxLength":254},"city":{"type":"string","enum":["New York","San Francisco","Los Angeles","Boston","Austin","Another city","Still deciding"]},"stage":{"type":"string","enum":["Planning my move","Recently arrived","Already settled"]},"profession":{"type":"string","minLength":2,"maxLength":120},"profileUrl":{"type":"string","maxLength":500,"default":"","description":"Optional full http:// or https:// professional profile URL with a valid hostname, or an empty string. Server validation is authoritative.","pattern":"^$|^[hH][tT][tT][pP][sS]?://"},"interests":{"type":"array","items":{"type":"string","enum":["Community meetups","Member introductions","Collaborations & opportunities","Member benefits","Expert connections","Hosting & contributing"]},"minItems":1,"maxItems":6},"introduction":{"type":"string","minLength":15,"maxLength":1500},"consent":{"type":"boolean","const":true,"description":"Set true only after the applicant has agreed to the privacy notice and application-related updates."},"immigrationCategory":{"type":"string","enum":["o1a","o1b","eb1a","eb1b","eb1c"]},"helpNeeded":{"type":"string","maxLength":1000,"default":""},"canOffer":{"type":"string","maxLength":1000,"default":""}},"required":["name","email","city","stage","profession","interests","introduction","consent","immigrationCategory"]},"ApplicationCreated":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"accessCode":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"Sensitive recovery credential. Save privately; do not index or share."},"accessExpiresAt":{"type":"string","format":"date-time"},"existing":{"type":"boolean","description":"Present when the caller already has access to the existing application. No new code is issued."}},"required":["ok","id"]}}},"paths":{"/api/public/club":{"get":{"operationId":"readClubFacts","summary":"Read public club facts","responses":{"200":{"description":"Public club identity, eligibility, current availability, and links."}}}},"/api/application-schema":{"get":{"operationId":"readApplicationRequirements","summary":"Read current field choices, limits, upload constraints and consent requirements","responses":{"200":{"description":"Current application contract derived from server validation."}}}},"/api/applications":{"post":{"operationId":"submitApplication","summary":"Submit an application with the applicant’s permission","description":"No third-party account is required. Explicit applicant privacy consent is required. Submit the introduction and self-declared category without a proof upload. Explain that redacted proof may be requested after the owner reviews the introduction. This saves an application but does not verify eligibility or approve membership. Retain the returned access code privately. Do not blindly retry a lost response: an existing application is never overwritten by email alone.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationInput"}}}},"responses":{"200":{"description":"Saved, or an already accessible application. New applications receive a private code and an HttpOnly browser cookie.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationCreated"}}}},"400":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"409":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"413":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"415":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"429":{"description":"Rate limit reached. Wait for the Retry-After interval before retrying.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}},"headers":{"Retry-After":{"description":"Minimum delay in seconds before another attempt.","schema":{"type":"integer","example":3600}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}}},"/api/membership":{"get":{"operationId":"readOwnApplication","summary":"Read the authorized application and review status","security":[{"ApplicationCode":[]},{"ApplicationCookie":[]}],"responses":{"200":{"description":"Own application, proof-request timestamp, proof metadata and any available invitation. Wait for a non-null verificationRequestedAt and pending status before uploading. A proof request or conditional acceptance is not final membership approval. Without valid access, application, proof and invitation are null. No document contents, owner notes, storage keys or access-code hashes are returned.","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"city":{"type":"string"},"stage":{"type":"string"},"profession":{"type":"string"},"interests":{"type":"string","description":"JSON-encoded array of selected interests."},"introduction":{"type":"string"},"status":{"type":"string","enum":["pending","waitlisted","approved","member"]},"immigrationCategory":{"type":"string","description":"One of the documented categories, or empty for a legacy application."},"helpNeeded":{"type":"string"},"canOffer":{"type":"string"},"verificationStatus":{"type":"string","enum":["missing","pending","verified","needs_changes"]},"verificationNote":{"type":"string","description":"Applicant-facing review note."},"verificationRequestedAt":{"type":["string","null"],"format":"date-time","description":"Owner’s proof-request timestamp. Upload only when this is non-null, status is pending, and evidence is not already verified. This is not final membership approval."},"verifiedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"verifiedEvidenceType":{"type":["string","null"]}}},"proof":{"type":["object","null"],"properties":{"uploadedAt":{"type":"string","format":"date-time"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer"},"evidenceType":{"type":"string"}}},"invitation":{"type":["object","null"],"description":"Private invitation. Follow only when the applicant explicitly chooses to join.","properties":{"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"}}}},"required":["application","proof","invitation"]}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}},"post":{"operationId":"withdrawApplication","summary":"Withdraw and remove an application after explicit confirmation","description":"Destructive. Get explicit confirmation from the applicant before calling. Removes application details, associated proof, review history, invitations, and site email records.","security":[{"ApplicationCode":[]},{"ApplicationCookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"const":"withdraw","type":"string"}},"required":["action"],"additionalProperties":false}}}},"responses":{"200":{"description":"Action completed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"401":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"413":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"415":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}}},"/api/membership/proof":{"post":{"operationId":"uploadPrivateProof","summary":"Upload requested redacted evidence","description":"Do not upload with the initial application. First read GET /api/membership and wait until application.verificationRequestedAt is non-null and application.status is pending. The owner requests proof after reviewing the introduction. A request or conditional acceptance is not final membership approval. HTTP 409 means uploading is not currently available, including before a request or while waitlisted. Require the applicant’s permission, their document, and their explicit redaction confirmation. Upload file bytes; remote URLs are unsupported. Only the owner can download the file. Approved evidence cannot be overwritten. Evidence must match the chosen O-1 or EB-1 category.","security":[{"ApplicationCode":[]},{"ApplicationCookie":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"One PDF, PNG or JPEG; maximum 4194304 bytes. Server checks size and signature."},"evidenceType":{"type":"string","enum":["o1_approval","o1_i94","o1_visa","eb1_approval","eb1_residence"]},"hasRedacted":{"type":"string","const":"true","description":"Only set after the applicant confirms ownership and redaction."},"immigrationCategory":{"type":"string","enum":["o1a","o1b","eb1a","eb1b","eb1c"],"description":"For legacy applications missing a category; otherwise must match the stored category."}},"required":["file","evidenceType","hasRedacted"],"additionalProperties":false}}}},"responses":{"200":{"description":"Action completed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"401":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"409":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"413":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"415":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"429":{"description":"Rate limit reached. Wait for the Retry-After interval before retrying.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}},"headers":{"Retry-After":{"description":"Minimum delay in seconds before another attempt.","schema":{"type":"integer","example":3600}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}},"delete":{"operationId":"removePrivateProof","summary":"Remove unreviewed evidence after explicit confirmation","description":"Destructive. Get confirmation from the applicant. Evidence is required before membership can be approved.","security":[{"ApplicationCode":[]},{"ApplicationCookie":[]}],"responses":{"200":{"description":"Action completed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"409":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}}},"/api/membership/access":{"post":{"operationId":"openPrivateApplication","summary":"Exchange a private access code for a browser cookie","description":"Use only a code supplied by the applicant. Invalid or expired codes do not reveal application details.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["code"],"additionalProperties":false}}}},"responses":{"200":{"description":"Action completed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"401":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"413":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"415":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}},"429":{"description":"Rate limit reached. Wait for the Retry-After interval before retrying.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}},"headers":{"Retry-After":{"description":"Minimum delay in seconds before another attempt.","schema":{"type":"integer","example":3600}}}},"503":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}},"delete":{"operationId":"closePrivateApplication","summary":"Clear private application access in this browser","description":"This clears the cookie; it does not delete the application or revoke the recovery code.","responses":{"200":{"description":"Action completed.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"403":{"description":"Request was not accepted. Read the stable code and any field errors before deciding whether to retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]}}},"required":["error","code"]}}}}}}}}}