openapi: 3.1.0
info:
  title: Newdrop Write API
  version: "1.0"
  description: |
    Ship What’s New from any agent or CI. Authorization: Bearer ndw_…
    Playbook: https://getnewdrop.com/ide-agent.md
    Errors: `{ "error": "code", "hint": "…" }` on 4xx/402/429.
servers:
  - url: https://getnewdrop.com
paths:
  /api/v1/write/me:
    get:
      operationId: writeMe
      summary: Confirm API key and list project URLs
      security:
        - bearerAuth: []
      responses:
        "200":
          description: OK
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/write/changelog:
    post:
      operationId: writeChangelog
      summary: Import Keep a Changelog markdown (live by default)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          text/markdown:
            schema:
              type: string
            example: |
              ## 1.2.0 — 2026-07-22
              ### Added
              - Dark mode
          application/json:
            schema:
              type: object
              properties:
                markdown:
                  type: string
                publish:
                  type: boolean
                  default: true
      responses:
        "200":
          description: Inserted / published counts + public_page
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PlanInactive"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/write/updates:
    post:
      operationId: writeUpdate
      summary: Create one update (draft by default; status published for live)
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title:
                  type: string
                body_md:
                  type: string
                tag:
                  type: string
                  enum: [new, improved, fixed]
                status:
                  type: string
                  enum: [draft, published]
                  default: draft
      responses:
        "200":
          description: Created update + public_page
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/PlanInactive"
        "429":
          $ref: "#/components/responses/RateLimited"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: ndw_… write API key from Setup → Connect AI pack
  schemas:
    ApiError:
      type: object
      required: [error]
      properties:
        error:
          type: string
        hint:
          type: string
  responses:
    Unauthorized:
      description: Missing or invalid write key
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            error: unauthorized
            hint: "Authorization: Bearer ndw_… (Setup → Connect AI pack)"
    BadRequest:
      description: Invalid body
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
    PlanInactive:
      description: Trial ended or plan inactive
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            error: plan_inactive
            hint: Trial ended or plan inactive — open Billing.
    RateLimited:
      description: Too many requests
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ApiError"
          example:
            error: rate_limited
            hint: Slow down — retry in about a minute.
