openapi: 3.1.0
info:
  title: Astronomy Core API
  version: 1.0.0
  description: |
    Sky data API for developers and AI agents.

    **Mission:** Astronomy Core — hosted astronomical and astrological JSON.

    ## Quick start for AI agents

    1. `GET /v1/capabilities` — discovery (no auth)
    2. Obtain `ac_live_...` via portal dashboard or `POST /v1/account/keys` (Firebase ID token)
    3. `GET /v1/snapshots?latitude=41.9&longitude=12.5&include=minimal` with `Authorization: Bearer ac_live_...`

    Calculations powered by [astronomy-engine](https://github.com/cosinekitty/astronomy) (MIT).
  contact:
    name: Astronomy Core
    url: https://astronomycore.com
  license:
    name: Proprietary API; engine MIT
    url: https://github.com/cosinekitty/astronomy

servers:
  - url: https://api.astronomycore.com
    description: Production API
  - url: https://astronomy-core-api.web.app
    description: Legacy Firebase Hosting URL

tags:
  - name: Discovery
    description: Public metadata for humans and LLM agents
  - name: Snapshots
    description: Full sky state at observer location/time
  - name: Bodies
    description: Single-body shortcuts
  - name: Charts
    description: Natal chart (tier feature)
  - name: Catalog
    description: Static reference data
  - name: Account
    description: API key management (Firebase ID token, not API key)

paths:
  /v1/capabilities:
    get:
      tags: [Discovery]
      summary: Discovery document
      description: LLM-friendly list of bodies, include groups, and endpoints. Use when bootstrapping an agent.
      operationId: getCapabilities
      responses:
        '200':
          description: Capabilities envelope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEnvelope'

  /v1/snapshots:
    get:
      tags: [Snapshots]
      summary: Solar system snapshot
      description: Use when you need positions, phases, rise/set, vectors for all bodies at once.
      operationId: getSnapshots
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: '#/components/parameters/latitude'
        - $ref: '#/components/parameters/longitude'
        - $ref: '#/components/parameters/datetime'
        - $ref: '#/components/parameters/elevation'
        - $ref: '#/components/parameters/pov'
        - $ref: '#/components/parameters/include'
      responses:
        '200':
          description: Snapshot envelope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEnvelope'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/QuotaExceeded'

  /v1/bodies/{body}:
    get:
      tags: [Bodies]
      summary: Single body data
      operationId: getBody
      security:
        - ApiKeyAuth: []
      parameters:
        - name: body
          in: path
          required: true
          schema:
            type: string
            enum: [sun, moon, mercury, venus, mars, jupiter, saturn, uranus, neptune, pluto]
        - $ref: '#/components/parameters/latitude'
        - $ref: '#/components/parameters/longitude'
        - $ref: '#/components/parameters/datetime'
        - $ref: '#/components/parameters/elevation'
        - $ref: '#/components/parameters/include'
      responses:
        '200':
          description: Body observer data envelope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEnvelope'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /v1/charts/natal:
    get:
      tags: [Charts]
      summary: Natal chart
      description: Planets in zodiac, ASC, MC, lunar nodes, equal houses, major aspects.
      operationId: getNatalChart
      security:
        - ApiKeyAuth: []
      parameters:
        - $ref: '#/components/parameters/latitude'
        - $ref: '#/components/parameters/longitude'
        - $ref: '#/components/parameters/datetime'
      responses:
        '200':
          description: Natal chart envelope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEnvelope'
        '403':
          description: Feature disabled for tier

  /v1/catalog/bodies:
    get:
      tags: [Catalog]
      summary: Celestial body metadata
      operationId: getCatalogBodies
      responses:
        '200':
          description: Catalog envelope

  /v1/account/keys:
    get:
      tags: [Account]
      summary: List API keys
      description: Requires Firebase ID token (portal session), not API key.
      operationId: listAccountKeys
      security:
        - FirebaseIdToken: []
      responses:
        '200':
          description: Key list with usage today
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiEnvelope'
    post:
      tags: [Account]
      summary: Create API key
      description: Plaintext key returned once in response.
      operationId: createAccountKey
      security:
        - FirebaseIdToken: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 64
                test:
                  type: boolean
                  description: If true, prefix ac_test_
      responses:
        '200':
          description: Created key (apiKey shown once)

  /v1/account/keys/{keyId}:
    delete:
      tags: [Account]
      summary: Revoke API key
      operationId: revokeAccountKey
      security:
        - FirebaseIdToken: []
      parameters:
        - name: keyId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Revoked

components:
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: API key with prefix ac_live_ or ac_test_
    FirebaseIdToken:
      type: http
      scheme: bearer
      description: Firebase Auth ID token from portal login

  parameters:
    latitude:
      name: latitude
      in: query
      required: true
      schema:
        type: number
        minimum: -90
        maximum: 90
    longitude:
      name: longitude
      in: query
      required: true
      schema:
        type: number
        minimum: -180
        maximum: 180
    datetime:
      name: datetime
      in: query
      required: false
      description: ISO 8601 UTC; defaults to now
      schema:
        type: string
        format: date-time
    elevation:
      name: elevation
      in: query
      schema:
        type: number
        default: 0
    pov:
      name: pov
      in: query
      schema:
        type: string
        default: earth
    include:
      name: include
      in: query
      schema:
        type: string
        default: all
        description: all, minimal, or comma-separated groups

  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'
    QuotaExceeded:
      description: Daily quota exceeded
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemDetails'

  schemas:
    ApiEnvelope:
      type: object
      required: [data, meta]
      properties:
        data: {}
        meta:
          $ref: '#/components/schemas/ResponseMeta'

    ResponseMeta:
      type: object
      properties:
        requestId:
          type: string
        computedAt:
          type: string
          format: date-time
        tier:
          type: string
        usage:
          type: object
          properties:
            dailyRemaining:
              type: integer

    ProblemDetails:
      type: object
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        code:
          type: string

    SolarSystemSnapshot:
      type: object
      description: Full snapshot with observerData, vectorData, timestamp

    NatalChart:
      type: object
      description: Planets, ascendant, midheaven, northNode, southNode, houseCusps, aspects

    AstronomicalData:
      type: object
      description: Single-body observer fields (altitude, phase, rise/set, zodiac, etc.)
