{"components":{"schemas":{"APIError":{"properties":{"error":{"description":"Stable machine-readable error code.","type":"string"},"message":{"description":"Human-readable error message.","type":"string"},"request_id":{"description":"Request identifier for support.","type":"string"}},"required":["error","message"],"type":"object"},"BatchRequest":{"properties":{"operations":{"items":{"properties":{"operationId":{"type":"string"}},"required":["operationId"],"type":"object"},"type":"array"}},"required":["operations"],"type":"object"},"BatchResponse":{"properties":{"results":{"items":{"type":"object"},"type":"array"}},"required":["results"],"type":"object"},"CVContent":{"properties":{"content":{"description":"CV markdown.","type":"string"},"is_default":{"type":"boolean"},"updated_at":{"format":"date-time","type":"string"}},"required":["content","is_default"],"type":"object"},"CVPageMeta":{"properties":{"favicon":{"format":"uri","type":"string"},"og_image":{"format":"uri","type":"string"}},"required":["favicon","og_image"],"type":"object"},"JobStatus":{"properties":{"job_id":{"type":"string"},"status":{"enum":["queued","running","succeeded","failed"],"type":"string"}},"required":["job_id","status"],"type":"object"},"NLWebAnswer":{"properties":{"answer":{"type":"string"},"query":{"type":"string"},"sources":{"items":{"properties":{"title":{"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url","title"],"type":"object"},"type":"array"}},"required":["answer","sources"],"type":"object"},"Pagination":{"properties":{"limit":{"maximum":100,"minimum":1,"type":"integer"},"next_cursor":{"type":"string"}},"required":["limit","next_cursor"],"type":"object"},"WebhookMetadata":{"properties":{"events":{"items":{"type":"string"},"type":"array"},"name":{"type":"string"},"register":{"type":"string"},"signing":{"type":"object"}},"required":["name","events","signing"],"type":"object"},"WebhookRegistration":{"properties":{"events":{"items":{"enum":["cv.content.updated"],"type":"string"},"type":"array"},"secret":{"type":"string","writeOnly":true},"url":{"format":"uri","type":"string"}},"required":["url","events"],"type":"object"}},"securitySchemes":{"ownerSSO":{"description":"Owner-only SSO for write operations; public read endpoints do not require auth.","flows":{"authorizationCode":{"authorizationUrl":"https://sso.laisky.com/","scopes":{"cv:read":"Read public CV data","cv:write":"Owner-only CV editing"},"tokenUrl":"https://sso.laisky.com/oauth/token"}},"type":"oauth2","x-publicRead":true}}},"externalDocs":{"description":"Agent-oriented CV summary.","url":"https://cv.laisky.com/llms.txt"},"info":{"contact":{"email":"job@laisky.com","name":"Zhonghua (Laisky) Cai","url":"https://cv.laisky.com/"},"description":"Public CV endpoints for agents and recruiting workflows.","title":"Zhonghua (Laisky) Cai CV API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/v1/batch":{"post":{"description":"Accepts a batch of read-only CV operations for agent clients.","operationId":"batchCVReadV1","parameters":[{"description":"Idempotency key for safe retries.","in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}},"description":"Batch response."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Invalid request."}},"summary":"Batch CV read operations."}},"/api/v1/cv":{"get":{"description":"Versioned public endpoint for current CV markdown and update metadata.","operationId":"getCurrentCVV1","parameters":[{"description":"Optional comma-separated sections to emphasize, for example summary,skills,experience.","in":"query","name":"include","required":false,"schema":{"type":"string"}},{"description":"Optional idempotency key for agent retries.","in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CVContent"}}},"description":"Current CV content.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Invalid request."},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Server error."}},"summary":"Read the current CV markdown."}},"/api/v1/jobs":{"post":{"description":"Creates a read-only placeholder job for agents testing async polling.","operationId":"createCVJobV1","responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"}}},"description":"Job accepted.","headers":{"Location":{"schema":{"type":"string"}}}}},"summary":"Create an async CV job."}},"/api/v1/jobs/{job_id}":{"get":{"description":"Returns status for long-running CV rendering jobs.","operationId":"getCVJobStatusV1","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatus"}}},"description":"Job status."}},"summary":"Read async job status."}},"/api/v1/sandbox/cv":{"get":{"description":"Non-destructive sandbox endpoint with the same response shape as the public CV read API.","operationId":"getSandboxCVV1","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CVContent"}}},"description":"Current CV content.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Invalid request."},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Server error."}},"summary":"Read sandbox CV markdown."}},"/api/v1/webhooks":{"get":{"description":"Returns supported events and signing metadata for owner-approved webhook registration.","operationId":"getCVWebhookDocsV1","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMetadata"}}},"description":"Webhook metadata."}},"summary":"Read webhook documentation."},"post":{"description":"Owner-approved webhook registration endpoint. Public read agents should treat this as discovery-only unless explicitly authorized.","operationId":"registerCVWebhookV1","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRegistration"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookMetadata"}}},"description":"Webhook metadata."}},"summary":"Register a CV webhook."}},"/ask":{"post":{"description":"NLWeb-compatible endpoint for simple CV question answering.","operationId":"askCVNLWeb","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NLWebAnswer"}}},"description":"NLWeb answer."}},"summary":"Ask a natural-language CV question."}},"/cv/content":{"get":{"description":"Returns the public CV in markdown with update metadata.","operationId":"getCurrentCV","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CVContent"}}},"description":"Current CV content.","headers":{"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"integer"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Invalid request."},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}},"description":"Server error."}},"summary":"Read the current CV markdown."}},"/cv/meta":{"get":{"description":"Returns resolved favicon and Open Graph image metadata.","operationId":"getCVPageMeta","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CVPageMeta"}}},"description":"Resolved CV page metadata."}},"summary":"Read page metadata for the CV site."}},"/cv/pdf":{"get":{"description":"Returns the rendered public CV PDF when available.","operationId":"downloadCurrentCVPDF","parameters":[{"description":"Optional cache-busting timestamp.","in":"query","name":"ts","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/pdf":{"schema":{"format":"binary","type":"string"}}},"description":"Current CV PDF."},"404":{"description":"PDF is not available yet."}},"summary":"Download the current CV as PDF."}}},"servers":[{"url":"https://cv.laisky.com"}],"x-api-versioning-policy":{"deprecation":"Breaking changes use a new URL version. Active versions send Deprecation: false and Sunset headers.","docs":"https://cv.laisky.com/api/versioning.md","stable":"/api/v1","style":"url"}}