{"openapi":"3.1.0","info":{"title":"Open Call Portals — Agent API","description":"Search active open call listings and upcoming live events, and submit new listings or responses through the email-verified write workflow. Read endpoints require no authentication and return PII-free structured data. Write endpoints (verify-email, confirm, post listing, respond) require email verification — the verified email address is the trust anchor for accountability.","version":"1.1.0","contact":{"url":"https://opencallportal.com"}},"servers":[{"url":"https://opencallportal.com/api","description":"Production"}],"paths":{"/agent/listings":{"get":{"operationId":"searchOpenCalls","summary":"Search active open call listings","description":"Returns venues and event hosts seeking DJs, live bands, comedians, artists, content creators, event crew, solopreneurs, and more. All active and PII-free.","parameters":[{"name":"portalId","in":"query","description":"Filter to one portal: dj, lb, cc, comedian, artist, casting, ec, solopreneur, gh, demo, poker, bowling, darts, cue-sports, golf-society, liquor-supply, local-produce, coworking, dance-acts, run-club, fs","schema":{"type":"string"}},{"name":"location","in":"query","description":"City or country name substring, e.g. 'london', 'uk'","schema":{"type":"string"}},{"name":"genre","in":"query","description":"Comma-separated genres, e.g. 'house,techno'","schema":{"type":"string"}},{"name":"type","in":"query","description":"Comma-separated open call types, e.g. 'paid-fixed-fee,residency'","schema":{"type":"string"}},{"name":"from","in":"query","description":"ISO date YYYY-MM-DD — listings closing on or after","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"ISO date YYYY-MM-DD — listings closing on or before","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","description":"Max results (default 100, max 500)","schema":{"type":"integer","default":100,"maximum":500}},{"name":"format","in":"query","description":"'json' (default) or 'md' for paste-ready markdown","schema":{"type":"string","enum":["json","md"]}}],"responses":{"200":{"description":"Active open call listings","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"listings":{"type":"array","items":{"type":"object"}}}}}}}}}},"/agent/live-events":{"get":{"operationId":"searchLiveEvents","summary":"Search upcoming live events","description":"Returns upcoming live events from the Live Events Map with geo coordinates (lat/lng), ticketing info, and source links.","parameters":[{"name":"location","in":"query","description":"City, venue name, or country substring","schema":{"type":"string"}},{"name":"type","in":"query","description":"Event types: dj, live-band, comedian, dance-acts","schema":{"type":"string"}},{"name":"genre","in":"query","description":"Comma-separated genres","schema":{"type":"string"}},{"name":"ticketed","in":"query","description":"yes | no | tbc","schema":{"type":"string","enum":["yes","no","tbc"]}},{"name":"from","in":"query","description":"ISO date YYYY-MM-DD","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"ISO date YYYY-MM-DD","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","description":"Max results (default 100, max 500)","schema":{"type":"integer","default":100,"maximum":500}}],"responses":{"200":{"description":"Upcoming live events with geo data","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"events":{"type":"array","items":{"type":"object"}}}}}}}}}},"/agent/schema":{"get":{"operationId":"getPlatformSchema","summary":"Get the full platform schema and write workflow","description":"Returns all portal IDs, field specs, MCP server details, and the email-verified listing submission workflow.","responses":{"200":{"description":"Platform schema and API contract","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/auth/verify-email":{"post":{"operationId":"sendVerificationCode","summary":"Step 1 — Send email verification code","description":"Sends a 6-digit one-time code to the provided email address. This is the first step in the write workflow — required before posting a listing or responding to one. The code expires after 10 minutes. In development the code is always 555555 and no real email is sent.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Email address to verify."},"portalId":{"type":"string","description":"Portal context for the verification email, e.g. 'dj', 'lb'. Defaults to 'dj'."}}},"example":{"email":"venue@example.com","portalId":"dj"}}}},"responses":{"200":{"description":"Code sent successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}},"example":{"message":"Verification code sent to your email."}}}},"429":{"description":"Rate limited — too many code requests for this email."}}}},"/auth/verify-email/confirm":{"post":{"operationId":"confirmVerificationCode","summary":"Step 2 — Confirm code and receive write token","description":"Confirms the 6-digit code sent by sendVerificationCode. Returns a verificationToken valid for 4 hours that can be used once. Pass this token to postListing or respondToListing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","code"],"properties":{"email":{"type":"string","format":"email","description":"Same email used in sendVerificationCode."},"code":{"type":"string","description":"6-digit code from the verification email (or '555555' in development)."}}},"example":{"email":"venue@example.com","code":"123456"}}}},"responses":{"200":{"description":"Code confirmed — token issued","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"email":{"type":"string"},"token":{"type":"string","description":"verificationToken — pass to postListing or respondToListing."}}},"example":{"verified":true,"email":"venue@example.com","token":"<verificationToken>"}}}},"400":{"description":"Invalid or expired code."}}}},"/listings":{"post":{"operationId":"postListing","summary":"Step 3a — Post an open call or availability listing","description":"Submits a new listing to the platform. Requires a verificationToken from confirmVerificationCode. The listing appears publicly once created. For full field specs per portal, call GET /api/agent/schema. For availability portals, append '-availability' to the portalId (e.g. 'dj-availability'). For live events use portalId 'live-event' and include eventTime.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["verificationToken","portalId"],"properties":{"verificationToken":{"type":"string","description":"Token from confirmVerificationCode."},"portalId":{"type":"string","description":"Target portal, e.g. 'dj', 'lb', 'dj-availability', 'live-event'."},"userRole":{"type":"string","description":"Posting role, e.g. 'venue-manager', 'promoter'."},"organizerName":{"type":"string","description":"Venue or organiser name."},"locationIds":{"type":"array","items":{"type":"integer"},"description":"Location IDs from GET /api/locations."},"date":{"type":"string","format":"date","description":"Event or opportunity date (YYYY-MM-DD)."},"closeDate":{"type":"string","format":"date","description":"Application closing date (YYYY-MM-DD)."},"openCallTypes":{"type":"array","items":{"type":"string"},"description":"e.g. ['paid-fixed-fee', 'residency']."},"genres":{"type":"array","items":{"type":"string"},"description":"e.g. ['house', 'techno']."},"note":{"type":"string","maxLength":500,"description":"Optional plain-text note."},"sourceApp":{"type":"string","description":"Your application name for attribution, e.g. 'BandBooker Pro'."},"eventTime":{"type":"string","format":"date-time","description":"ISO datetime — required for live-event portal."}}},"example":{"verificationToken":"<token from step 2>","portalId":"dj","userRole":"venue-manager","organizerName":"The Blue Room","locationIds":[1],"date":"2026-10-15","closeDate":"2026-10-15","openCallTypes":["paid-fixed-fee"],"genres":["house","techno"]}}}},"responses":{"201":{"description":"Listing created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"uiReference":{"type":"string","description":"Human-readable ref, e.g. 'DJ-3456'."},"portalId":{"type":"string"}}},"example":{"id":1234,"uiReference":"DJ-3456","portalId":"dj"}}}},"400":{"description":"Validation error — missing required fields or invalid token."}}}},"/listings/{id}/respond":{"post":{"operationId":"respondToListing","summary":"Step 3b — Respond to an open call on behalf of a performer","description":"Submits a response (pitch / application) to an open call listing. The listing creator is notified by email. Requires a verificationToken from confirmVerificationCode. The email in the body must match the verified token's email. Use searchOpenCalls to find numeric listing IDs.","parameters":[{"name":"id","in":"path","required":true,"description":"Numeric listing ID from searchOpenCalls.","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["verificationToken","email","name","emailConsent"],"properties":{"verificationToken":{"type":"string","description":"Token from confirmVerificationCode."},"email":{"type":"string","format":"email","description":"Respondent's email — must match the verified token."},"name":{"type":"string","description":"Respondent's name or act name."},"message":{"type":"string","description":"Cover message / pitch to the listing creator."},"soundcloudUrl":{"type":"string","description":"SoundCloud or portfolio link."},"instagramUrl":{"type":"string","description":"Instagram or social link."},"epk":{"type":"string","description":"Electronic Press Kit URL."},"emailConsent":{"type":"boolean","description":"Must be true — respondent consents to sharing contact details with the listing creator."}}},"example":{"verificationToken":"<token from step 2>","email":"dj@example.com","name":"DJ Example","message":"Hi, I'd love to play at your venue. Here's my SoundCloud...","soundcloudUrl":"https://soundcloud.com/djexample","emailConsent":true}}}},"responses":{"200":{"description":"Response submitted — listing creator notified by email","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}},"example":{"message":"Response submitted successfully."}}}},"400":{"description":"Validation error or invalid token."},"404":{"description":"Listing not found."}}}}}}