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

# Edit a benchmark

> Change an existing benchmark the same way create_from_spec creates one. Send any of `title`, `description`, `terms`, `pages`, `contact_email`, `organization_name`, `reward`, `report` and `items`; anything else is refused. Everything except `items` is documentation: it changes in place and stays editable however much has been run against the benchmark. `pages` are the benchmark's markdown tabs, sent in display order. Both `pages` and `items` replace their whole list rather than being merged in, so send back the entries you want to keep. Sending `items` revalidates the whole list (5-2000 entries, the same rules as creation), rebuilds the question datasets and repoints the benchmark's tasks at them. Questions can only be replaced while nothing has been run against the benchmark: a finished run's score describes the questions it saw, and a run in flight would read a dataset that changed under it, so both answer 409 with a `runs` count and you should create a new benchmark instead. Editing never changes whether the benchmark is published, who it is shared with, or its phases. Only the creator and its collaborators may edit. Requires the `benchmark:edit` scope, which is narrower than `benchmark:manage` and cannot delete a benchmark, reshape its phases or mail its participants.



## OpenAPI

````yaml POST /api/competitions/{id}/edit_spec/
openapi: 3.0.3
info:
  title: BenchGen Platform API
  version: 1.0.0
  description: >-
    One API for the whole BenchGen platform: model catalogue and serving,
    fine-tuning and benchmarks, datasets (knowledge), and billing.


    ## Authentication

    Every request uses the same credential: a platform API token sent as
    `Authorization: Bearer bgn_...`.

    Create tokens in the web app under Profile Settings > Platform API tokens
    (the secret is shown exactly once), or via `POST /api/tokens/` with an
    interactive session. Revoking a token disables it platform-wide within 60
    seconds.


    ## Scopes

    A token carries scopes chosen at creation; a request outside the token's
    scopes gets `403` with an explanatory message.


    | scope | grants |

    |---|---|

    | `models:read` | read model catalogues, job status, logs, GPU info |

    | `models:write` | deploy, train, merge, stop models and jobs |

    | `benchmark:read` | read benchmark runs and results |

    | `benchmark:run` | launch benchmark runs |

    | `benchmark:create` | create benchmarks in your account (drafts, Excel,
    bundles, specs); counts toward the creation limit |

    | `benchmark:manage` | edit and delete benchmarks you own or collaborate on
    |

    | `benchmark:publish` | publish and unpublish benchmarks you own or
    collaborate on |

    | `knowledge:read` | read your datasets and fine-tuning data |

    | `knowledge:write` | create, edit and delete datasets and fine-tuning data
    |

    | `billing:read` | read your balance and usage |

    | `agents:chat` | chat with your own agents through the API |

    | `agents:manage` | manage your agents, knowledge bases and channels |

    | `admin` | everything the account can do (staff accounts only) |


    ## For agents

    This document plus `/api/llms.txt` are the machine-readable entry points.
    Responses are JSON. Errors use conventional status codes; the body carries
    `error` or `message`. Knowledge endpoints return `[{"data": [...], "meta":
    {...}}]`.


    The complete auto-generated schema of every endpoint (including internal
    ones) lives at `/api/public-docs.json` (Swagger 2.0); this document is the
    curated, stable, supported surface.
  contact:
    url: https://benchgen.com
servers:
  - url: https://api.benchgen.com
security:
  - platformToken: []
tags:
  - name: auth
    description: Token introspection for services and integrations
  - name: tokens
    description: Manage your platform API tokens
  - name: models
    description: Model catalogue and serving
  - name: finetune
    description: Fine-tuning jobs, inference deployments, GPUs
  - name: knowledge
    description: Datasets and fine-tuning data (knowledge API)
  - name: billing
    description: Balance and usage
  - name: agents
    description: Chat with your agents (OpenAI-compatible facade)
  - name: benchmark
    description: Public benchmark (competition) listings.
paths:
  /api/competitions/{id}/edit_spec/:
    post:
      tags:
        - benchmark
      summary: Edit a benchmark from a JSON spec
      description: >-
        Change an existing benchmark the same way create_from_spec creates one.
        Send any of `title`, `description`, `terms`, `pages`, `contact_email`,
        `organization_name`, `reward`, `report` and `items`; anything else is
        refused. Everything except `items` is documentation: it changes in place
        and stays editable however much has been run against the benchmark.
        `pages` are the benchmark's markdown tabs, sent in display order. Both
        `pages` and `items` replace their whole list rather than being merged
        in, so send back the entries you want to keep. Sending `items`
        revalidates the whole list (5-2000 entries, the same rules as creation),
        rebuilds the question datasets and repoints the benchmark's tasks at
        them. Questions can only be replaced while nothing has been run against
        the benchmark: a finished run's score describes the questions it saw,
        and a run in flight would read a dataset that changed under it, so both
        answer 409 with a `runs` count and you should create a new benchmark
        instead. Editing never changes whether the benchmark is published, who
        it is shared with, or its phases. Only the creator and its collaborators
        may edit. Requires the `benchmark:edit` scope, which is narrower than
        `benchmark:manage` and cannot delete a benchmark, reshape its phases or
        mail its participants.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Benchmark id
        - name: dry_run
          in: query
          required: false
          schema:
            type: boolean
          description: >-
            Validate only: answers 200 with a summary and a preview, and changes
            nothing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >-
                At least one of title, description, terms, pages, contact_email,
                organization_name, reward, report or items
              properties:
                title:
                  type: string
                  example: Unit Conversion Basics, revised
                description:
                  type: string
                terms:
                  type: string
                contact_email:
                  type: string
                  format: email
                organization_name:
                  type: string
                  maxLength: 256
                reward:
                  type: string
                  maxLength: 256
                report:
                  type: string
                  maxLength: 256
                pages:
                  type: array
                  maxItems: 20
                  items:
                    type: object
                    required:
                      - title
                    properties:
                      title:
                        type: string
                        maxLength: 255
                      content:
                        type: string
                        description: Markdown body; may be empty
                  description: >-
                    The complete new page list, in display order, replacing the
                    old one
                type:
                  type: string
                  enum:
                    - question_answer
                    - multiple_choice
                  description: >-
                    Optional and only together with items; inferred from the
                    items when omitted
                items:
                  type: array
                  minItems: 5
                  maxItems: 2000
                  items:
                    type: object
                    required:
                      - question
                      - answer
                    properties:
                      question:
                        type: string
                      answer:
                        type: string
                        description: >-
                          Short text answer, or for choices the letter (A, B,
                          ...) or the exact text of the correct choice
                      choices:
                        type: array
                        items:
                          type: string
                        description: 2-10 options; makes the spec multiple_choice
                      context:
                        type: string
                        description: Optional passage for question_answer items
                      group:
                        type: string
                        description: Optional topic or category used to group results
                  description: The complete new question list, replacing the old one
      responses:
        '200':
          description: Edited, or with dry_run the summary of what would change
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: boolean
                  id:
                    type: integer
                  title:
                    type: string
                  slug:
                    type: string
                  published:
                    type: boolean
                  changed:
                    type: array
                    items:
                      type: string
                    description: Which of title, description and items actually changed
                  kind:
                    type: string
                    description: Present when items were sent
                  pages:
                    type: integer
                    nullable: true
                    description: >-
                      How many pages were sent, null when the edit left them
                      alone
                  items:
                    type: integer
                    nullable: true
                    description: >-
                      How many items were sent, null when the edit left the
                      questions alone
                  tasks_updated:
                    type: integer
                    description: How many tasks got the rebuilt datasets
                  preview:
                    type: array
                    items:
                      type: object
                    description: >-
                      dry_run only: the first few items as the platform read
                      them
        '400':
          description: The edit is not usable; `errors` lists every problem found
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: boolean
                  errors:
                    type: array
                    items:
                      type: string
        '403':
          description: Not your benchmark, or the token lacks benchmark:edit
        '404':
          description: No such benchmark
        '409':
          description: The benchmark has been run, so its questions cannot be replaced
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: string
                    example: benchmark_has_runs
                  detail:
                    type: string
                  runs:
                    type: object
                    properties:
                      finished_runs:
                        type: integer
                      active_runs:
                        type: integer
      security:
        - platformToken: []
        - interactiveToken: []
        - session: []
components:
  securitySchemes:
    platformToken:
      type: http
      scheme: bearer
      bearerFormat: bgn_ opaque token
      description: >-
        Platform API token created under Profile Settings > Platform API tokens.
        Scopes are fixed at creation.
    interactiveToken:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Interactive token from `POST /api/api-token-auth/`, sent as
        `Authorization: Token <token>`. Unlike a platform `bgn_` token this is a
        full interactive credential (it is minted from your password), so it may
        create and revoke platform tokens. Keep it out of CI; put a scoped
        `bgn_` token there instead.
    session:
      type: apiKey
      in: cookie
      name: sessionid
      description: >-
        Interactive browser session, the `sessionid` cookie Django sets when you
        sign in to the web app (benchgen.com). To script this endpoint, sign in
        in a browser and copy the `sessionid` cookie from DevTools > Application
        > Cookies. The recommended path is simply the web app itself: Profile
        Settings > Platform API tokens. Platform tokens are deliberately refused
        here (403), so a leaked token can never mint successors.

````