> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kalligator.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create or save a draft

> Creates a draft or saves changes to a draft. You choose the report ID: make a new UUIDv4. Because the ID is yours, a retry never makes a duplicate report.

Send `revision: 0` for a new draft. After that, send the `revision` from the last response. If the draft changed in a different session, the API returns `409 revision_conflict` with the stored report in `current`.

You can only edit a report in `draft` status. You cannot change `program_id` after you create the draft. Your email must be verified.



## OpenAPI

````yaml /api-reference/openapi.json put /api/reports/{report_id}
openapi: 3.1.0
info:
  title: Kalligator API
  description: >-
    The Kalligator API gives you all the hacker functions of the website. Use it
    to find programs, write and submit reports, upload evidence, and reply to
    the triage agent.


    Send `Authorization: Bearer kal_...` with an API key from the **API keys**
    section of your account page. The full guide is at
    https://docs.kalligator.com/api-reference/introduction.
  version: '1'
servers:
  - url: https://kalligator.com
    description: Production
security: []
tags:
  - name: Programs
    description: Published programs that accept reports.
  - name: Reports
    description: Drafts, submission, and withdrawal of your reports.
  - name: Files
    description: Evidence files that you attach to a report or to a message.
  - name: Messages
    description: The thread between you, the triage agent, and the Kalligator team.
  - name: Account
    description: Your account status and payout setup.
  - name: API keys
    description: >-
      Keys that let your agent or script act for you. Key management needs a
      website sign-in.
  - name: Account emails
    description: Email verification and password reset.
paths:
  /api/reports/{report_id}:
    put:
      tags:
        - Reports
      summary: Create or save a draft
      description: >-
        Creates a draft or saves changes to a draft. You choose the report ID:
        make a new UUIDv4. Because the ID is yours, a retry never makes a
        duplicate report.


        Send `revision: 0` for a new draft. After that, send the `revision` from
        the last response. If the draft changed in a different session, the API
        returns `409 revision_conflict` with the stored report in `current`.


        You can only edit a report in `draft` status. You cannot change
        `program_id` after you create the draft. Your email must be verified.
      operationId: save_report_api_reports__report_id__put
      parameters:
        - name: report_id
          in: path
          required: true
          schema:
            type: string
            format: uuid4
            title: Report Id
          description: A UUIDv4 that you make for a new draft, or the ID of your draft.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReportInput'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Report'
        4XX:
          description: '`{detail, code}`; see the error codes in the API description'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Retry after `Retry-After` seconds when it is set
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - HTTPBearer: []
components:
  schemas:
    ReportInput:
      properties:
        program_id:
          type: string
          pattern: ^[a-z0-9-]{1,80}$
          title: Program Id
          description: >-
            The program for the report. You cannot change it after you create
            the draft.
        title:
          type: string
          maxLength: 180
          title: Title
          description: A short title, at most 180 characters.
        asset:
          type: string
          maxLength: 1000
          title: Asset
          description: >-
            The affected asset, for example a URL, host, app, or repository. At
            most 1000 characters.
        description:
          type: string
          maxLength: 30000
          title: Description
          description: >-
            Markdown, at most 30000 characters. Use the headings for steps to
            reproduce, expected behavior, actual behavior, and security impact.
        cvss_vector:
          type: string
          maxLength: 100
          title: Cvss Vector
          default: ''
          description: >-
            Optional. Your CVSS 3.1 base vector, for example
            `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`. Send an empty string
            for none.
        revision:
          type: integer
          minimum: 0
          title: Revision
          description: '`0` for a new draft. Otherwise the current `revision` of the report.'
      additionalProperties: false
      type: object
      required:
        - program_id
        - title
        - asset
        - description
        - revision
      title: ReportInput
    Report:
      properties:
        id:
          type: string
          title: Id
        program_id:
          type: string
          title: Program Id
        program_name:
          type: string
          title: Program Name
        status:
          type: string
          enum:
            - draft
            - triaging
            - needs_info
            - paused
            - human_review
            - accepted
            - rejected
            - duplicate
            - insufficient_info
            - withdrawn
          title: Status
          description: The report status. See the report lifecycle guide.
        display_status:
          type: string
          title: Display Status
          description: The status text that the website shows.
        title:
          type: string
          title: Title
        revision:
          type: integer
          title: Revision
          description: >-
            Increases when you save the draft, upload or remove a file, submit,
            or withdraw. Send the latest value with your next change.
        created_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Created At
        updated_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Updated At
        submitted_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Submitted At
        withdrawn_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Withdrawn At
        asset:
          type: string
          title: Asset
        description:
          type: string
          title: Description
        cvss_vector:
          type: string
          title: Cvss Vector
        attachments:
          additionalProperties:
            $ref: '#/components/schemas/Attachment'
          type: object
          title: Attachments
          description: Files on the report, by file ID.
        submission:
          anyOf:
            - $ref: '#/components/schemas/Submission'
            - type: 'null'
          description: >-
            The frozen copy of the report, files, and program policy at
            submission. `null` for a draft.
        decision:
          anyOf:
            - $ref: '#/components/schemas/Decision'
            - type: 'null'
          description: The final decision and an optional message. `null` until a decision.
        payout:
          anyOf:
            - $ref: '#/components/schemas/Payout'
            - type: 'null'
          description: >-
            Your reward payment. `null` until the Kalligator team approves the
            reward.
      additionalProperties: false
      type: object
      required:
        - id
        - program_id
        - program_name
        - status
        - display_status
        - title
        - revision
        - created_at
        - updated_at
        - submitted_at
        - withdrawn_at
        - asset
        - description
        - cvss_vector
        - attachments
        - submission
        - decision
      title: Report
    Error:
      properties:
        detail:
          type: string
          title: Detail
          description: A message for a person.
        code:
          type: string
          title: Code
          description: A stable `snake_case` error code.
        current:
          anyOf:
            - $ref: '#/components/schemas/Report'
            - type: 'null'
          description: 'Only on `409 revision_conflict`: the stored report.'
      additionalProperties: false
      type: object
      required:
        - detail
        - code
      title: Error
      description: Every error has this body. Make decisions on `code`, not on `detail`.
    Attachment:
      properties:
        name:
          type: string
          title: Name
        size:
          type: integer
          title: Size
        content_type:
          type: string
          title: Content Type
        sha256:
          type: string
          title: Sha256
          description: The SHA-256 hash of the file bytes.
        storage_path:
          type: string
          title: Storage Path
        state:
          type: string
          enum:
            - uploading
            - ready
            - failed
            - deleting
          title: State
          description: >-
            `ready` files can be referenced and downloaded. `uploading` and
            `failed` files block submission.
        started_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Started At
        uploaded_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Uploaded At
        generation:
          anyOf:
            - type: string
            - type: 'null'
          title: Generation
        reply:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Reply
          description: '`true` for a message file.'
        message_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Message Id
          description: The message that sent the file. `null` while the file waits.
      additionalProperties: false
      type: object
      required:
        - name
        - size
        - content_type
        - sha256
        - storage_path
        - state
        - started_at
      title: Attachment
    Submission:
      properties:
        submitted_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Submitted At
        attachments:
          additionalProperties:
            $ref: '#/components/schemas/Attachment'
          type: object
          title: Attachments
        content:
          $ref: '#/components/schemas/Content'
        program:
          $ref: '#/components/schemas/SubmittedProgram'
        stripe:
          $ref: '#/components/schemas/SubmittedStripe'
      additionalProperties: false
      type: object
      required:
        - submitted_at
        - attachments
        - content
        - program
        - stripe
      title: Submission
    Decision:
      properties:
        outcome:
          type: string
          enum:
            - accepted
            - rejected
            - duplicate
            - insufficient_info
          title: Outcome
        at:
          anyOf:
            - type: string
            - type: 'null'
          title: At
        message:
          anyOf:
            - type: string
            - type: 'null'
          title: Message
      additionalProperties: false
      type: object
      required:
        - outcome
        - at
        - message
      title: Decision
    Payout:
      properties:
        status:
          type: string
          enum:
            - approving
            - transferred
            - received
            - payout_failed
          title: Status
          description: >-
            `approving`, then `transferred`, then `received`. `payout_failed` if
            the bank payout failed.
        amount_cents:
          type: integer
          title: Amount Cents
          description: The reward in US cents.
        approved_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Approved At
        transferred_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Transferred At
        received_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Received At
        payout_failed_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Payout Failed At
      additionalProperties: false
      type: object
      required:
        - status
        - amount_cents
        - approved_at
        - transferred_at
        - received_at
        - payout_failed_at
      title: Payout
      description: >-
        The researcher's view of an approved reward; null until the founder
        approves it.
    Content:
      properties:
        title:
          type: string
          title: Title
        asset:
          type: string
          title: Asset
        description:
          type: string
          title: Description
        cvss_vector:
          type: string
          title: Cvss Vector
          default: ''
      additionalProperties: false
      type: object
      required:
        - title
        - asset
        - description
      title: Content
    SubmittedProgram:
      properties:
        policy_version:
          type: integer
          title: Policy Version
        name:
          type: string
          title: Name
        scope:
          type: string
          title: Scope
        exclusions:
          type: string
          title: Exclusions
        rules:
          type: string
          title: Rules
        eligibility:
          type: string
          title: Eligibility
        disclosure:
          type: string
          title: Disclosure
        rewards:
          additionalProperties:
            type: integer
          propertyNames:
            enum:
              - low
              - medium
              - high
              - critical
          type: object
          title: Rewards
      additionalProperties: false
      type: object
      required:
        - policy_version
        - name
        - scope
        - exclusions
        - rules
        - eligibility
        - disclosure
        - rewards
      title: SubmittedProgram
    SubmittedStripe:
      properties:
        status:
          type: string
          title: Status
        checked_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Checked At
      additionalProperties: false
      type: object
      required:
        - status
        - checked_at
      title: SubmittedStripe
  securitySchemes:
    HTTPBearer:
      type: http
      description: A Firebase ID token, or a Kalligator API key (`kal_…`).
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.