openapi: 3.0.3
info:
  title: RoleRank
  version: "1.0.0"
  description: Durable fit scoring across official ATS job-board APIs. Bearer API key.
  termsOfService: https://rolerank.agentstructure.ai/terms
  contact:
    name: RoleRank
    url: https://rolerank.agentstructure.ai/links
    email: support@agentstructure.ai
  license:
    name: Proprietary
servers:
  - url: https://rolerank.agentstructure.ai
    description: Production
paths:
  /api/health:
    get:
      summary: Health
      responses:
        "200":
          description: ok
  /api/v1/brief:
    get:
      summary: Morning ranked list as a WhatsApp message
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: message plus cards }
    post:
      summary: Résumé in, ranked WhatsApp message out
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                resumeText: { type: string }
                filename: { type: string }
      responses:
        "200": { description: Immediate ranked message }
  /api/v1/profile:
    get:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Living profile }
    post:
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema: { type: object }
      responses:
        "200": { description: Upserted profile }
  /api/v1/profile/resume:
    post:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Parsed résumé merged }
  /api/v1/watchlist:
    get:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Authorized boards }
    put:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Replaced watchlist }
  /api/v1/watchlist/boards:
    post:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Board added }
  /api/v1/scan:
    post:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Scan summary }
  /api/v1/opportunity-events:
    get:
      summary: Unread high-confidence opportunity events (proactive feed)
      description: Poll this feed, surface each event to the user, then acknowledge it. Events never repeat once acknowledged.
      security: [{ bearerAuth: [] }]
      parameters:
        - { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 50, default: 10 } }
      responses:
        "200": { description: count plus events with job title, company, score, posted_at, apply_url, reasons, gaps }
  /api/v1/opportunity-events/{eventId}/ack:
    post:
      summary: Acknowledge an opportunity event after surfacing it to the user
      security: [{ bearerAuth: [] }]
      parameters:
        - { name: eventId, in: path, required: true, schema: { type: string } }
      responses:
        "200": { description: acknowledged }
        "404": { description: unread event not found }
  /api/v1/slate:
    get:
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: min_score
          schema: { type: integer, default: 80 }
        - in: query
          name: new_only
          schema: { type: boolean }
        - in: query
          name: limit
          schema: { type: integer, default: 20 }
      responses:
        "200": { description: Scored cards }
  /api/v1/alerts/glasses:
    get:
      security: [{ bearerAuth: [] }]
      responses:
        "200":
          description: Spoken glasses payload
  /api/v1/alerts/ack:
    post:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: Marked spoken }
  /api/v1/diff:
    get:
      security: [{ bearerAuth: [] }]
      responses:
        "200": { description: New 80-plus since last scan }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
