Hyperresearch Projects API

Projects: one body of sources, its runs and its reports

GitHub OpenAPI

Operations 4

GET /v1/projects List projects #
POST /v1/projects Create a project #
GET /v1/projects/{id} Get a project #
PATCH /v1/projects/{id} Rename, re-describe or archive a project #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/hyperresearch-ai:hyperresearch-ai-projects-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

hyperresearch-ai-projects-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: hyperresearch Cloud Projects API
  version: 1.0.0
  description: 'REST v1 for hosted hyperresearch runs, vault access, verification, and billing. Times are RFC 3339 UTC; ids are prefixed ULIDs.


    **Authentication.** Send an API key as `Authorization: Bearer hr_live_…`. Each operation lists the scope it needs (`x-hr-scope`, and in its `security` requirement). OAuth 2.1 (authorization code + PKCE, `oauth2` scheme) issues tokens for the hosted MCP server at https://mcp.hyperresearch.ai/mcp; REST calls use an API key.


    **Errors.** Every 4xx/5xx body is the `ErrorEnvelope`: `error.type`, a stable `error.code`, a human `message`, the offending `param` when there is one, and the `request_id` to quote to support. Branch on `code`, never on `message`.


    **Rate limits.** Responses carry `RateLimit-Policy` and `RateLimit` (draft-ietf-httpapi-ratelimit-headers) alongside the older `X-RateLimit-*` headers. A 429 always carries `Retry-After` (seconds) and `error.retry_after`.


    **Versioning.** The version is in the path. `/v1` is stable: within it, changes are additive only (new operations, new optional request fields, new response fields, new enum values a client must tolerate). A breaking change ships only under a new path version. A deprecated operation is marked `deprecated: true` here and answers with `Deprecation` (RFC 9745) and `Sunset` (RFC 8594) headers and `Link: rel="deprecation"` at least six months before it is removed, and is listed under Deprecations on the policy page: https://hyperresearch.ai/docs/versioning'
  contact:
    name: hyperresearch
    url: https://hyperresearch.ai
  x-api-lifecycle:
    version_scheme: path
    current: v1
    status: stable
    breaking_changes: new path version only
    deprecation_notice_min_days: 182
    deprecation_signals:
    - 'openapi deprecated: true'
    - Deprecation header (RFC 9745)
    - Sunset header (RFC 8594)
    - Link rel="deprecation"
    - policy page deprecations list
    policy: https://hyperresearch.ai/docs/versioning
servers:
- url: https://api.hyperresearch.ai
  description: production
tags:
- name: Projects
  description: 'Projects: one body of sources, its runs and its reports'
paths:
  /v1/projects:
    get:
      tags:
      - Projects
      summary: List projects
      description: Projects in this workspace, most recently updated first. `status` defaults to `active`; pass `archived` or `all` to widen it. `counts.runs`, `counts.reports` and `counts.sources` come from one statement over one snapshot, so this list and `GET /v1/projects/{id}` can never publish different totals for the same project. `counts.sources` is `SUM(runs.sources_fetched)` — the sources these runs kept.
      operationId: listProjects
      x-hr-scope: runs:read
      x-hr-auth: key-or-session
      security:
      - bearerAuth:
        - runs:read
      - sessionCookie:
        - runs:read
      parameters:
      - schema:
          type: string
          enum:
          - active
          - archived
          - all
          description: Defaults to `active`.
        required: false
        description: Defaults to `active`.
        name: status
        in: query
      responses:
        '200':
          description: Projects
          headers:
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectList'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Insufficient scope or plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limited or over quota
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
    post:
      tags:
      - Projects
      summary: Create a project
      description: Names are trimmed and unique per workspace (exact, case-sensitive, archived projects included); a duplicate is a 409 `project_name_taken`. A new project starts `active` with no runs. An `Idempotency-Key` replays the first 201 for 24 hours; the same key with a different body is a 409 `idempotency_key_reuse`.
      operationId: createProject
      x-hr-scope: runs:write
      x-hr-auth: key-or-session
      security:
      - bearerAuth:
        - runs:write
      - sessionCookie:
        - runs:write
      parameters:
      - schema:
          type: string
          minLength: 1
          maxLength: 255
        required: false
        name: idempotency-key
        in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateProjectBody'
      responses:
        '201':
          description: Project created
          headers:
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Insufficient scope or plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: A project with this name already exists in the workspace, or the Idempotency-Key was reused with a different body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limited or over quota
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
  /v1/projects/{id}:
    get:
      tags:
      - Projects
      summary: Get a project
      description: One project, in exactly the shape `GET /v1/projects` returns for it. `counts.sources` is `SUM(runs.sources_fetched)` over the runs filed here — the sources they kept — computed in the same statement as `counts.runs` and `counts.reports`, so this endpoint and the list never disagree (E2E5-03).
      operationId: getProject
      x-hr-scope: runs:read
      x-hr-auth: key-or-session
      security:
      - bearerAuth:
        - runs:read
      - sessionCookie:
        - runs:read
      parameters:
      - schema:
          type: string
          minLength: 3
          maxLength: 64
          example: proj_01J9ZQ7V6H0000000000000000
        required: true
        name: id
        in: path
      responses:
        '200':
          description: Project
          headers:
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Insufficient scope or plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limited or over quota
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
    patch:
      tags:
      - Projects
      summary: Rename, re-describe or archive a project
      description: Archiving keeps every existing run filed and readable; it only refuses NEW runs (409 `project_archived`). Set `status` back to `active` to reopen it.
      operationId: updateProject
      x-hr-scope: runs:write
      x-hr-auth: key-or-session
      security:
      - bearerAuth:
        - runs:write
      - sessionCookie:
        - runs:write
      parameters:
      - schema:
          type: string
          minLength: 3
          maxLength: 64
          example: proj_01J9ZQ7V6H0000000000000000
        required: true
        name: id
        in: path
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchProjectBody'
      responses:
        '200':
          description: Project
          headers:
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Insufficient scope or plan
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: A project with this name already exists in the workspace
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limited or over quota
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            RateLimit-Policy:
              $ref: '#/components/headers/RateLimit-Policy'
            RateLimit:
              $ref: '#/components/headers/RateLimit'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Bucket:
              $ref: '#/components/headers/X-RateLimit-Bucket'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              enum:
              - invalid_request
              - authentication
              - permission
              - not_found
              - rate_limited
              - quota_exceeded
              - budget_blocked
              - conflict
              - provider_unavailable
              - internal
              example: invalid_request
            code:
              type: string
              enum:
              - missing_api_key
              - malformed_api_key
              - invalid_api_key
              - api_key_expired
              - api_key_revoked
              - account_suspended
              - workspace_unavailable
              - session_expired
              - insufficient_scope
              - signup_closed
              - role_not_permitted
              - membership_required
              - csrf_required
              - csrf_invalid
              - origin_not_allowed
              - https_required
              - key_route_restricted
              - tier_not_allowed
              - runs_paused
              - invalid_body
              - invalid_query
              - invalid_path
              - query_too_short
              - query_not_research
              - query_too_long
              - query_refused
              - invalid_title
              - invalid_brief
              - invalid_must_read
              - invalid_research_brief
              - invalid_time_window
              - invalid_pulse
              - invalid_metadata
              - invalid_tier
              - too_many_required_headings
              - sources_max_above_ceiling
              - reuse_scope_needs_project
              - invalid_webhook_url
              - metadata_too_large
              - invalid_settings
              - invalid_step
              - unsupported_tier
              - tier_not_offered
              - plan_not_offered
              - provider_excluded
              - dry_run_not_enabled
              - invalid_dry_run_fault
              - chaos_faults_not_enabled
              - invalid_chaos_fault
              - gone
              - run_not_found
              - key_not_found
              - workspace_not_found
              - webhook_not_found
              - artifact_not_found
              - note_not_found
              - escalation_not_found
              - source_not_found
              - connection_not_found
              - project_not_found
              - answer_not_found
              - account_not_found
              - feature_not_enabled
              - idempotency_key_reuse
              - idempotency_in_flight
              - run_not_resumable
              - run_not_finish_resumable
              - run_finish_resume_exhausted
              - run_recovering
              - rerun_not_platform
              - platform_rerun_taken
              - run_not_clarifying
              - result_not_ready
              - verification_running
              - workspace_not_empty
              - turnstile_invalid
              - turnstile_replayed
              - demo_daily_limit
              - demo_receipt_invalid
              - demo_disabled
              - anon_session_invalid
              - anon_refine_limit
              - anon_refine_capacity
              - refine_draft_not_found
              - user_not_found
              - member_not_found
              - member_exists
              - last_owner
              - cannot_self_elevate
              - workspace_limit
              - invitation_not_found
              - invitation_expired
              - invitation_email_mismatch
              - account_mismatch
              - ip_not_allowed
              - chat_keys_retired
              - project_name_taken
              - project_archived
              - run_not_filable
              - confirmation_mismatch
              - ownership_transfer_required
              - account_deleting
              - export_cooldown
              - migration_pending
              - rate_limit_exceeded
              - concurrency_limit
              - spend_cap_exceeded
              - trial_exhausted
              - payment_method_required
              - payment_disputed
              - card_hold_unavailable
              - card_required
              - fixture_not_shareable
              - too_many_url_sources
              - no_citations
              - insufficient_balance
              - wallet_frozen
              - topup_amount_invalid
              - topup_daily_limit
              - answers_capacity
              - engine_unavailable
              - temporarily_unavailable
              - platform_capacity
              - daily_run_limit
              - internal_budget
              - orchestrator_unavailable
              - source_unconfigured
              - source_rate_limited
              - source_upstream_unavailable
              - deployment_misconfigured
              - not_implemented
              - pdf_unavailable
              - internal_error
              example: query_too_short
            message:
              type: string
            param:
              type: string
            retry_after:
              type: integer
            retryable:
              type: boolean
              description: 'Whether the same request may succeed if sent again unchanged (after `retry_after` when present): true for 429, 500, 502, 503, 504 and `idempotency_in_flight`; false for every other 4xx and 501.'
            request_id:
              type: string
              example: req_01J9ZQ7V6H0000000000000000
          required:
          - type
          - code
          - message
          - retryable
          - request_id
      required:
      - error
    PatchProjectBody:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 80
        description:
          type:
          - string
          - 'null'
          maxLength: 500
        status:
          type: string
          enum:
          - active
          - archived
    ProjectList:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/Project'
      required:
      - items
    ProjectLatestRun:
      type:
      - object
      - 'null'
      properties:
        id:
          type: string
          example: run_01J9ZQ7V6H0000000000000000
        status:
          type: string
        tier:
          type: string
        created_at:
          type: string
        started_at:
          type:
          - string
          - 'null'
          description: When the run actually began, as opposed to when it was queued.
        finished_at:
          type:
          - string
          - 'null'
          description: When the run ENDED, null while it is still going. The project header says "latest finished N ago" and was printing `created_at` — the moment the run was launched — so a run that finished three minutes ago read as nineteen minutes ago (E2E7-09). Read this for that sentence.
        duration_ms:
          type:
          - integer
          - 'null'
          description: Wall time of the run; the same number `GET /v1/runs` and `GET /v1/runs/{id}` serve.
        query_preview:
          type:
          - string
          - 'null'
          description: Server-derived excerpt of that run’s canonical question.
      required:
      - id
      - status
      - tier
      - created_at
      - started_at
      - finished_at
      - duration_ms
      - query_preview
    Project:
      type: object
      properties:
        id:
          type: string
          example: proj_01J9ZQ7V6H0000000000000000
        name:
          type: string
        description:
          type:
          - string
          - 'null'
        status:
          type: string
          enum:
          - active
          - archived
        created_at:
          type: string
        updated_at:
          type: string
        counts:
          $ref: '#/components/schemas/ProjectCounts'
        latest_run:
          $ref: '#/components/schemas/ProjectLatestRun'
      required:
      - id
      - name
      - description
      - status
      - created_at
      - updated_at
      - counts
      - latest_run
    CreateProjectBody:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 80
          example: EU AI Act enforcement
        description:
          type: string
          maxLength: 500
      required:
      - name
    ProjectCounts:
      type: object
      properties:
        runs:
          type: integer
          description: Runs filed under this project.
        reports:
          type: integer
          description: Those runs that finished (`done`).
        sources:
          type: integer
          description: 'Sources the runs filed here KEPT, summed: `SUM(runs.sources_fetched)` over the runs filed here, under the same definition as `runs.sources_fetched` on a run (a failed attempt is not a source). Computed in the same statement as `runs` and `reports`, so the list and the detail always agree; a run that has recorded no count yet contributes 0.'
      required:
      - runs
      - reports
      - sources
  headers:
    Retry-After:
      description: Seconds to wait before retrying. Always present on a 429.
      schema:
        type: integer
        minimum: 0
    X-RateLimit-Remaining:
      description: Requests left in this window (legacy form of `RateLimit`).
      schema:
        type: integer
        minimum: 0
    X-RateLimit-Bucket:
      description: 'Which bucket counted the request: `reads`, `status`, `creates`, `writes` or `public`.'
      schema:
        type: string
    RateLimit-Policy:
      description: 'The quota policy this request was counted against (draft-ietf-httpapi-ratelimit-headers): `"<bucket>";q=<requests>;w=<window seconds>`, e.g. `"reads";q=60;w=60`. Buckets: `reads` 60/min, `status` 600/min, `creates` 10/min, `writes` 20/min per credential; `public` 300/min per network on keyless routes.'
      schema:
        type: string
        example: '"reads";q=60;w=60'
    X-RateLimit-Limit:
      description: Requests allowed per window in this bucket (legacy form of `RateLimit-Policy`).
      schema:
        type: integer
        minimum: 0
    X-RateLimit-Reset:
      description: Unix time (seconds) when the window resets.
      schema:
        type: integer
        minimum: 0
    RateLimit:
      description: 'Remaining quota in the current window: `"<bucket>";r=<remaining>;t=<seconds until reset>`, e.g. `"reads";r=57;t=41`.'
      schema:
        type: string
        example: '"reads";r=57;t=41'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An API key: `hr_live_…` (billed), `hr_test_…` (fixture mode, free), or `hr_chat_…` (vault chat only).'
    sessionCookie:
      type: apiKey
      in: cookie
      name: hr_session
      description: Console session cookie (HttpOnly, set by `POST /v1/auth/clerk/exchange`). Mutations also require an allowlisted `Origin` and the `X-CSRF-Token` header. The requirement list names the workspace-role scope the session must carry.
    clerkAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: A Clerk-issued session JWT, exchanged once for an `hr_session` cookie. Not a hyperresearch API key.
    oauth2:
      type: oauth2
      description: 'OAuth 2.1 for agents (MCP clients): authorization code with PKCE (S256), public clients, dynamic client registration at `https://api.hyperresearch.ai/oauth/register`, discovery at `https://api.hyperresearch.ai/.well-known/oauth-authorization-server`. Access tokens (15 min) and rotating refresh tokens (30 days) are bound to the resource `https://mcp.hyperresearch.ai/mcp` and are accepted by the hosted MCP server, not by the REST operations in this document, which take an API key (`bearerAuth`). A member can only delegate scopes their workspace role holds; the token response reports the granted `scope`.'
      flows:
        authorizationCode:
          authorizationUrl: https://api.hyperresearch.ai/oauth/authorize
          tokenUrl: https://api.hyperresearch.ai/oauth/token
          refreshUrl: https://api.hyperresearch.ai/oauth/token
          scopes:
            mcp: Connect to the hosted MCP server; every OAuth grant carries it.
            vault:read: 'Read and search the workspace vault: notes, claims, sources, hubs, escalations, scholar lookups.'
            runs:read: 'Read runs: status, event stream, results, reports and artifacts.'
            vault:write: 'Write to the workspace vault: create/update/delete notes, ingest claims, import, resolve escalations.'
            runs:write: Start, clarify, pause, resume, abort and re-run research runs (billable).
            fetch: Fetch a URL into the vault on the workspace’s budget (billable; OAuth grants only, checked against the member’s role).
            verify: Run citation, quote, retraction and independence verification jobs and read their results (billable).
            answers:ask: 'Answers: `ask` and `search` calls billed per call from the prepaid wallet, plus reading the wallet balance (billable).'
externalDocs:
  description: hyperresearch API documentation
  url: https://hyperresearch.ai/docs