{"components":{"schemas":{"AttachedFile":{"description":"One uploaded input file.","properties":{"content_type":{"description":"MIME type as reported by the upload, or ``application/octet-stream`` when unknown.","title":"Content Type","type":"string"},"filename":{"description":"Path-safe filename committed to the workspace.","title":"Filename","type":"string"},"size_bytes":{"description":"File size in bytes.","title":"Size Bytes","type":"integer"}},"required":["filename","size_bytes","content_type"],"title":"AttachedFile","type":"object"},"BillingTransactionItem":{"description":"One wallet transaction.","properties":{"amount_cents":{"description":"Dollar amount in cents (positive = credit added, negative = consumed).","title":"Amount Cents","type":"integer"},"balance_after_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Wallet balance immediately after this transaction.","title":"Balance After Cents"},"created_at":{"description":"ISO 8601 — when the transaction posted.","format":"date-time","title":"Created At","type":"string"},"depth_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Effort tier the consumed job ran at, if applicable.","title":"Depth Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Free-form note (e.g. ``Top-up via Stripe``).","title":"Description"},"id":{"description":"Stable transaction identifier.","title":"Id","type":"string"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The research job that consumed credits, if applicable.","title":"Job Id"},"receipt_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Stripe-hosted receipt URL for paid deposits.","title":"Receipt Url"},"stripe_payment_intent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Stripe payment intent for paid deposits.","title":"Stripe Payment Intent Id"},"type":{"description":"Transaction type: ``deposit``, ``consumption``, ``bonus``, ``refund``, ``expiration``, or ``auto_topup``.","title":"Type","type":"string"}},"required":["id","created_at","type","amount_cents"],"title":"BillingTransactionItem","type":"object"},"BillingUsageByEffort":{"description":"Per-effort spend breakdown for the requested period.","properties":{"cents":{"default":0,"description":"Dollar value of those credits, in cents.","title":"Cents","type":"integer"},"credits":{"default":0,"description":"Credits consumed across those jobs.","title":"Credits","type":"integer"},"jobs":{"default":0,"description":"Number of jobs run at this effort tier.","title":"Jobs","type":"integer"}},"title":"BillingUsageByEffort","type":"object"},"BillingUsageResponse":{"description":"Aggregated credit spend over a billing window.\n\n``low`` (free tier) is omitted from ``by_effort`` because it\ndoesn't produce a wallet transaction. ``cents_spent_paid``\nreports out-of-pocket spend only — it excludes credits that came\nfrom your subscription bundle or referral bonuses.","properties":{"by_effort":{"additionalProperties":{"$ref":"#/components/schemas/BillingUsageByEffort"},"description":"Per-effort breakdown keyed by effort tier (``medium``, ``high``, ``build``).","title":"By Effort","type":"object"},"cents_spent_paid":{"default":0,"description":"Out-of-pocket dollar spend in cents (PAYG wallet draws only).","title":"Cents Spent Paid","type":"integer"},"job_count":{"default":0,"description":"Distinct jobs that consumed credits in the window.","title":"Job Count","type":"integer"},"period_end":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"ISO 8601 — end of the aggregation window.","title":"Period End"},"period_start":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"ISO 8601 — start of the aggregation window.","title":"Period Start"},"projected_period_end_credits":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Linear projection of credits remaining at the end of the period at current burn rate.","title":"Projected Period End Credits"},"total_cents_spent":{"default":0,"description":"Dollar value of those credits, in cents.","title":"Total Cents Spent","type":"integer"},"total_credits_used":{"default":0,"description":"Total credits consumed in the window.","title":"Total Credits Used","type":"integer"}},"title":"BillingUsageResponse","type":"object"},"Body_create_research_attachment_v2":{"properties":{"files":{"description":"One or more files to upload as a reusable research attachment.","items":{"format":"binary","type":"string"},"title":"Files","type":"array"}},"required":["files"],"title":"Body_create_research_attachment_v2","type":"object"},"CursorPage_BillingTransactionItem_":{"properties":{"has_more":{"default":false,"title":"Has More","type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/BillingTransactionItem"},"title":"Items","type":"array"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"required":["items"],"title":"CursorPage[BillingTransactionItem]","type":"object"},"CursorPage_ResearchJobListItem_":{"properties":{"has_more":{"default":false,"title":"Has More","type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/ResearchJobListItem"},"title":"Items","type":"array"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"required":["items"],"title":"CursorPage[ResearchJobListItem]","type":"object"},"CursorPage_TimelineEvent_":{"properties":{"has_more":{"default":false,"title":"Has More","type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/TimelineEvent"},"title":"Items","type":"array"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"required":["items"],"title":"CursorPage[TimelineEvent]","type":"object"},"ExpertSummary":{"description":"One entry in the discoverable expert list.\n\nSurfaced on ``GET /mpp/v1/api/experts`` and (curated subset) on\n``GET /mpp/v1/api`` under ``featured_experts``. Stays narrow — no\ninternal mcp_tools / skills / system_prompt plumbing.","properties":{"description":{"description":"Brief description of the expert's specialty.","title":"Description","type":"string"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Domain area (e.g., ``Supply Chain Research, Global Trade``).","title":"Domain"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Lucide icon name (UI hint).","title":"Icon"},"id":{"description":"Expert id, used as ``expert_id`` on POST /research.","title":"Id","type":"string"},"name":{"description":"Display name (e.g., ``Patent & IP``).","title":"Name","type":"string"},"output_types":{"description":"What this expert reliably produces. ``report`` = markdown. ``html_app`` / ``slidedeck`` / ``spreadsheet`` for app-builder. ``podcast`` / ``video`` / ``news_broadcast`` for media-producer.","items":{"type":"string"},"title":"Output Types","type":"array"},"sample_questions":{"description":"Example prompts that route well to this expert. Agents can pattern-match against the user's request to pick the right expert without LLM inference.","items":{"type":"string"},"title":"Sample Questions","type":"array"}},"required":["id","name","description"],"title":"ExpertSummary","type":"object"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"title":"Detail","type":"array"}},"title":"HTTPValidationError","type":"object"},"QuotaCheckResponse":{"description":"Result of a non-consuming quota pre-flight.","properties":{"allowed":{"description":"True if the caller has enough credits to run at this effort.","title":"Allowed","type":"boolean"},"credits_remaining":{"description":"Credits the caller has right now.","title":"Credits Remaining","type":"integer"},"credits_required":{"description":"How many credits this effort would cost.","title":"Credits Required","type":"integer"},"effort":{"description":"Echo of the requested effort tier.","title":"Effort","type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"When ``allowed=false``, a short reason (e.g. ``insufficient_credits``).","title":"Reason"}},"required":["allowed","effort","credits_required","credits_remaining"],"title":"QuotaCheckResponse","type":"object"},"QuotaResponse":{"description":"Caller's current quota and credit balance.","properties":{"bonus_credits":{"default":0,"description":"Credits from referrals or promos (consumed first).","title":"Bonus Credits","type":"integer"},"credit_quota":{"description":"Total credits granted in the current period.","title":"Credit Quota","type":"integer"},"credits_remaining":{"description":"Credits available to spend right now.","title":"Credits Remaining","type":"integer"},"credits_required_for_effort":{"additionalProperties":{"type":"integer"},"description":"Credit cost of one ``POST /research`` call at each effort tier.","title":"Credits Required For Effort","type":"object"},"credits_used_this_period":{"default":0,"description":"Credits consumed since the period start.","title":"Credits Used This Period","type":"integer"},"current_period_end":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"ISO 8601 — when the period resets.","title":"Current Period End"},"current_period_start":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"ISO 8601 — start of the current billing period.","title":"Current Period Start"},"tier":{"description":"Subscription tier the caller is on (e.g. ``free``, ``pro``, ``team``).","title":"Tier","type":"string"}},"required":["tier","credits_remaining","credit_quota"],"title":"QuotaResponse","type":"object"},"ResearchAttachmentDeleteResponse":{"description":"Response from ``DELETE /attachments/{attachment_id}``.","properties":{"attachment_id":{"description":"Stable attachment UUID.","format":"uuid","title":"Attachment Id","type":"string"},"status":{"description":"Always ``deleted`` after a successful delete.","title":"Status","type":"string"}},"required":["attachment_id","status"],"title":"ResearchAttachmentDeleteResponse","type":"object"},"ResearchAttachmentResponse":{"description":"Response from public v2 attachment endpoints.","properties":{"attachment_id":{"description":"Stable attachment UUID.","format":"uuid","title":"Attachment Id","type":"string"},"expires_at":{"description":"ISO 8601 expiration timestamp.","title":"Expires At","type":"string"},"files":{"description":"Uploaded files in this attachment.","items":{"$ref":"#/components/schemas/AttachedFile"},"title":"Files","type":"array"},"status":{"description":"Attachment lifecycle status.","title":"Status","type":"string"}},"required":["attachment_id","status","expires_at"],"title":"ResearchAttachmentResponse","type":"object"},"ResearchCancelResponse":{"description":"Response from ``POST /research/{id}/cancel``.","properties":{"already_terminal":{"default":false,"description":"True when the job was already terminal and no new cancel signal was sent.","title":"Already Terminal","type":"boolean"},"interrupted_check_result_ids":{"description":"CheckResult IDs moved to ``interrupted`` by this request.","items":{"type":"string"},"title":"Interrupted Check Result Ids","type":"array"},"job_id":{"description":"Stable UUID identity for the cancelled job.","title":"Job Id","type":"string"},"previous_status":{"description":"Status before this cancellation request.","title":"Previous Status","type":"string"},"signaled_keys":{"description":"Redis job/check-result keys that received a cancel signal.","items":{"type":"string"},"title":"Signaled Keys","type":"array"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL-friendly handle, if available.","title":"Slug"},"status":{"description":"Current terminal status. Usually ``cancelled``.","title":"Status","type":"string"}},"required":["job_id","status","previous_status"],"title":"ResearchCancelResponse","type":"object"},"ResearchContinuationCreate":{"additionalProperties":false,"description":"Request body for continuing a completed research job.","properties":{"context":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Additional context for this continuation turn.","title":"Context"},"effort":{"default":"low","description":"Effort tier for the continuation turn.","enum":["low","medium","high","build"],"title":"Effort","type":"string"},"idempotency_key":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional body-level idempotency key. The ``Idempotency-Key`` header takes precedence when both are supplied.","title":"Idempotency Key"},"instructions":{"description":"Instructions for the continuation turn. The agent resumes the completed job's Claude session and updates the existing research workspace/report in place.","title":"Instructions","type":"string"},"json_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"Optional structured-output schema for the updated report.","title":"Json Schema"},"referenceJobs":{"description":"Optional Grep research job UUIDs or slugs to make available as read-only code.storage workspace references for this continuation.","items":{"type":"string"},"title":"Reference Jobs","type":"array"},"render_rich_report":{"default":false,"description":"Render the report with widget:html visualisations (cover page, charts, diagrams, callouts). Default false produces a clean markdown report (headings, prose, markdown tables, inline citations) suitable for API/MCP consumers piping the output into their own pipelines. The Parcha UI sends true to get the rich rendered experience.","title":"Render Rich Report","type":"boolean"},"response_language":{"default":"en","description":"ISO 639-1 language code for the updated report.","title":"Response Language","type":"string"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Webhook URL POSTed when the continued job reaches a terminal state. API-key authentication only.","title":"Webhook Url"}},"required":["instructions"],"title":"ResearchContinuationCreate","type":"object"},"ResearchContinuationResponse":{"description":"Response from ``POST /research/{id}/continue``.","properties":{"continuation_id":{"description":"CheckResult UUID for this continuation turn.","title":"Continuation Id","type":"string"},"created_at":{"description":"ISO 8601 timestamp for the continuation row.","title":"Created At","type":"string"},"idempotent_replay":{"default":false,"description":"True when this response replays a previous request with the same idempotency key.","title":"Idempotent Replay","type":"boolean"},"job_id":{"description":"Stable UUID identity for the continued job.","title":"Job Id","type":"string"},"previous_status":{"description":"Status before the continuation request.","title":"Previous Status","type":"string"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL-friendly handle, if available.","title":"Slug"},"status":{"description":"Current job status after enqueueing continuation.","title":"Status","type":"string"}},"required":["job_id","status","previous_status","continuation_id","created_at"],"title":"ResearchContinuationResponse","type":"object"},"ResearchFileEntry":{"description":"One file in a research job's workspace.","properties":{"can_preview":{"default":false,"description":"Whether the file can be rendered inline.","title":"Can Preview","type":"boolean"},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type.","title":"Content Type"},"extension":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"File extension (e.g. ``md``, ``json``).","title":"Extension"},"file_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"High-level file type (e.g. ``text``, ``image``, ``data``).","title":"File Type"},"modified_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — last commit that touched this file.","title":"Modified At"},"path":{"description":"Slash-separated path relative to the job's workspace root.","title":"Path","type":"string"},"size_bytes":{"description":"File size in bytes.","title":"Size Bytes","type":"integer"}},"required":["path","size_bytes"],"title":"ResearchFileEntry","type":"object"},"ResearchFilesList":{"description":"Response from ``GET /research/{id}/files`` — the file listing.","properties":{"files":{"description":"All files in the workspace.","items":{"$ref":"#/components/schemas/ResearchFileEntry"},"title":"Files","type":"array"},"job_id":{"description":"Job UUID the listing is for.","title":"Job Id","type":"string"}},"required":["job_id"],"title":"ResearchFilesList","type":"object"},"ResearchJobCreate":{"additionalProperties":false,"description":"Request body for starting a research job.","properties":{"attachment_ids":{"description":"Attachment UUIDs returned by ``POST /attachments``. The server copies those files into the job workspace so the agent can read them from ``./input_files/``.","items":{"format":"uuid","type":"string"},"maxItems":10,"title":"Attachment Ids","type":"array"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Additional context for the research — gets passed through to the planner as background info on the question.","title":"Context"},"effort":{"default":"low","description":"How deeply to research. ``low`` returns a quick answer (~10–20 s), ``medium`` produces a structured report (~2–3 min), ``high`` runs an in-depth multi-phase investigation (~8–15 min), and ``build`` produces a creative artefact (HTML app, dataset, slides, …).","enum":["low","medium","high","build"],"title":"Effort","type":"string"},"expert_id":{"anyOf":[{"maxLength":255,"type":"string"},{"type":"null"}],"description":"Pin a specific research expert. Accepts: (a) a built-in registry id (e.g. ``individual-aml-compliance-expert``); (b) a custom expert UUID you own (or have been granted access to via expert sharing); (c) a custom expert slug. When omitted, an expert is auto-selected based on the question. Access is checked at request-validate time against the same rule the chat surface uses — if you can view the expert, you can dispatch against it.","title":"Expert Id"},"json_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"Optional JSON Schema describing structured fields you want the agent to populate in addition to the prose report. When supplied, the agent treats the schema as a checklist and researches every field — the result lands under ``structured_output`` on the detail response. The body must be a JSON object (anything else 422s on the request); the contents are treated as a JSON Schema by the agent, but Grep does not run schema-meta-validation server-side — supply a valid JSON Schema (``type``, ``properties``, etc.) so the agent can use it.","title":"Json Schema"},"model":{"anyOf":[{"enum":["opus","sonnet","haiku"],"type":"string"},{"type":"null"}],"title":"Model"},"question":{"description":"The research question to investigate.","title":"Question","type":"string"},"referenceJobs":{"description":"Optional Grep research job UUIDs or slugs to make available as read-only code.storage workspace references for this run.","items":{"type":"string"},"title":"Reference Jobs","type":"array"},"render_rich_report":{"default":false,"description":"Render the report with widget:html visualisations (cover page, charts, diagrams, callouts). Default false produces a clean markdown report (headings, prose, markdown tables, inline citations) suitable for API/MCP consumers piping the output into their own pipelines. The Parcha UI sends true to get the rich rendered experience.","title":"Render Rich Report","type":"boolean"},"response_language":{"default":"en","description":"ISO 639-1 language code for the rendered report.","title":"Response Language","type":"string"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Webhook URL POSTed when the job reaches a terminal state.","title":"Webhook Url"}},"required":["question"],"title":"ResearchJobCreate","type":"object"},"ResearchJobDetail":{"description":"Single-job detail returned by ``GET /api/v2/research/{job_id_or_slug}``.\n\nStrict shape (no ``extra=\"allow\"`` catch-all). What you see is the\ncontract; nothing else leaks through. Job IDs accept either a UUID\nor a slug — see ``resolve_job_id`` in v1 for the lookup logic.","properties":{"attachments":{"description":"Input attachments copied into ``./input_files/`` for this job.","items":{"$ref":"#/components/schemas/ResearchAttachmentResponse"},"title":"Attachments","type":"array"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — when execution ended.","title":"Completed At"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Caller-supplied context.","title":"Context"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601.","title":"Created At"},"effort":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Effort level the job was created with (matches ``POST /research``).","title":"Effort"},"expert_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Pinned expert ID, if the caller specified one. Empty when the expert was auto-selected from the question.","title":"Expert Id"},"is_public":{"default":false,"description":"If true, the job is publicly viewable.","title":"Is Public","type":"boolean"},"job_id":{"description":"Stable UUID identity.","title":"Job Id","type":"string"},"json_schema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"Echo of the JSON Schema the caller supplied at job start, if any. ``None`` when the job was created without a ``json_schema`` field on the request body.","title":"Json Schema"},"question":{"description":"The research question.","title":"Question","type":"string"},"report":{"anyOf":[{"$ref":"#/components/schemas/ResearchReport"},{"type":"null"}],"description":"The rendered ``report.md`` content + the commit it was read from. ``None`` for queued/running jobs (no report yet). Read at the head of ``main`` at request time."},"response_language":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Report language (ISO 639-1 code).","title":"Response Language"},"revisions":{"description":"Published revisions of the report, newest first. Pass a ``commit_sha`` from this list as ``?revision=<sha>`` on this endpoint to read the report at that historical revision.","items":{"$ref":"#/components/schemas/ResearchRevision"},"title":"Revisions","type":"array"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL-friendly handle.","title":"Slug"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — when execution began.","title":"Started At"},"status":{"description":"Job lifecycle status.","title":"Status","type":"string"},"structured_output":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"description":"Agent-populated structured output conforming to ``json_schema``. Present only when (a) the job supplied a schema at start and (b) the agent has finished and filled it. ``None`` for queued / running / failed jobs and for jobs that never asked for structured output.","title":"Structured Output"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — last server-side mutation.","title":"Updated At"}},"required":["job_id","status","question"],"title":"ResearchJobDetail","type":"object"},"ResearchJobListItem":{"description":"Single row in ``GET /api/v2/research`` — the lean list view.\n\nCarries enough to render a list, decide whether to drill in, and\nlink by slug. Everything else (approach, effort, file listing,\nreport content) zooms in via ``GET /api/v2/research/{id}``.","properties":{"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — when the job finished.","title":"Completed At"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — when the job was created.","title":"Created At"},"effort":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Effort tier the job ran at: ``ultra_fast``, ``deep``, ``ultra_deep``, ``low``, ``medium``, ``high``, or ``build``.","title":"Effort"},"job_id":{"description":"Stable UUID identity for the job.","title":"Job Id","type":"string"},"question":{"description":"The research question the job is answering.","title":"Question","type":"string"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL-friendly handle. May be null for very old jobs.","title":"Slug"},"status":{"description":"Lifecycle: ``queued``, ``moderation``, ``planning``, ``running``, ``completed``, ``failed``, ``cancelled``, ``blocked``.","title":"Status","type":"string"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 — last server-side mutation (status change, slug assignment, etc).","title":"Updated At"}},"required":["job_id","status","question"],"title":"ResearchJobListItem","type":"object"},"ResearchJobResponse":{"description":"Response from starting a research job.","properties":{"job_id":{"title":"Job Id","type":"string"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"status":{"title":"Status","type":"string"}},"required":["job_id","status"],"title":"ResearchJobResponse","type":"object"},"ResearchReport":{"description":"The rendered ``report.md`` payload inlined on detail responses.","properties":{"markdown":{"description":"Raw Markdown content of the current report.","title":"Markdown","type":"string"},"revision_sha":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Commit SHA the report was read from. ``None`` when the job has not produced a checkpoint yet (the report was read from the default branch tip but no revision metadata exists).","title":"Revision Sha"}},"required":["markdown"],"title":"ResearchReport","type":"object"},"ResearchRevision":{"description":"One published revision of the research report.\n\nPass the ``commit_sha`` to ``GET /research/{id}?revision=<sha>``\nto re-read the report at that point in time.","properties":{"actor_label":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Which agent wrote the revision (e.g. ``research-agent``).","title":"Actor Label"},"checkpoint_type":{"description":"``new_subjob`` (root revision) or ``continuation`` (incremental update).","title":"Checkpoint Type","type":"string"},"commit_message":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Author-provided revision notes, if any.","title":"Commit Message"},"commit_sha":{"description":"Full git commit SHA.","title":"Commit Sha","type":"string"},"created_at":{"description":"ISO 8601 — when this revision was published.","title":"Created At","type":"string"}},"required":["commit_sha","created_at","checkpoint_type"],"title":"ResearchRevision","type":"object"},"ResearchVisibilityResponse":{"description":"Response body for ``PATCH /api/v2/research/{job_id_or_slug}``.","properties":{"is_public":{"description":"The new visibility state after the update.","title":"Is Public","type":"boolean"},"job_id":{"description":"Stable UUID identity of the job.","title":"Job Id","type":"string"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"URL-friendly handle, if any.","title":"Slug"},"updated_at":{"description":"ISO 8601 timestamp of the mutation.","title":"Updated At","type":"string"}},"required":["job_id","is_public","updated_at"],"title":"ResearchVisibilityResponse","type":"object"},"ResearchVisibilityUpdate":{"additionalProperties":false,"description":"Request body for ``PATCH /api/v2/research/{job_id_or_slug}``.\n\nCurrently the only mutable field is ``is_public``. Additional\nfields will be appended here as the partial-update surface grows.","properties":{"is_public":{"description":"When ``true``, the job is publicly viewable without authentication (capability reads of the report, files, and timeline succeed). When ``false``, the job reverts to owner/admin-only access.","title":"Is Public","type":"boolean"}},"required":["is_public"],"title":"ResearchVisibilityUpdate","type":"object"},"TimelineEvent":{"description":"One event in a research job's execution timeline.\n\nReturned in DESC order (newest first) by ``GET\n/research/{job_id_or_slug}/timeline``. Customers drive a\n\"what's the agent doing right now?\" UI off this without our\nSDK content shape becoming a public contract.","properties":{"agent_label":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Friendly identifier for the agent that emitted the event (e.g. ``grep-research-v2``). Today this is the orchestrator key for every event in a job; sub-agent identity is encoded in ``summary`` instead.","title":"Agent Label"},"created_at":{"description":"DB-write time, ISO 8601. The keyset cursor encodes this column.","title":"Created At","type":"string"},"id":{"description":"Stable event UUID — also the keyset cursor anchor.","title":"Id","type":"string"},"kind":{"description":"Event type. One of ``thinking``, ``text_block``, ``tool_use``, ``tool_result``, ``phase``, ``subagent_started``, ``subagent_progress``, ``subagent_completed``, ``final_answer``, ``error``. Unknown / internal event kinds are filtered out before the response is built.","title":"Kind","type":"string"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Human-readable one-liner describing what happened (e.g. ``Using tool: Bash``, ``Subagent working: Search for Stripe`` — the same string the dashboard shows). Truncated to 500 characters. ``None`` for events that have no narratable status.","title":"Summary"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Human-readable text the agent produced. For ``kind=text_block`` this is the response chunk; for ``kind=thinking`` this is the reasoning trace. Truncated to 2000 characters.","title":"Text"},"timestamp":{"description":"Worker-side wall-clock when the event happened, ISO 8601. May be slightly behind ``created_at`` for events that queue before being persisted.","title":"Timestamp","type":"string"},"tool_input_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For ``kind=tool_use``: a short, sanitized rendering of the tool input (typically the description plus the first characters of the command). Env-var values are redacted and absolute paths obfuscated. Truncated to 500 characters.","title":"Tool Input Preview"},"tool_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Tool name when ``kind`` is ``tool_use`` or ``tool_result`` (e.g. ``Read``, ``Bash``, ``WebSearch``).","title":"Tool Name"},"tool_result_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For ``kind=tool_result``: first 500 characters of the tool output, sanitized. Use ``tool_result_size_bytes`` to detect truncation.","title":"Tool Result Preview"},"tool_result_size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"For ``kind=tool_result``: byte length of the FULL tool output (before truncation). When this exceeds the preview length, fetch the workspace file via ``GET /research/{id}/files/{path}`` for the full content.","title":"Tool Result Size Bytes"},"tool_status":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"For ``kind=tool_result``: ``\"success\"`` or ``\"failed\"``. ``None`` for non-result events.","title":"Tool Status"},"tool_use_id":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Stable tool-call identifier. The same value appears on the matching ``tool_use`` and ``tool_result`` events; use it to pair them in client code.","title":"Tool Use Id"}},"required":["id","timestamp","created_at","kind"],"title":"TimelineEvent","type":"object"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"title":"Location","type":"array"},"msg":{"title":"Message","type":"string"},"type":{"title":"Error Type","type":"string"}},"required":["loc","msg","type"],"title":"ValidationError","type":"object"}},"securitySchemes":{"GrepApiKeyBearer":{"bearerFormat":"Grep API key","description":"Use a Grep API key in the Authorization header: Bearer parcha-...","scheme":"bearer","type":"http"},"GrepOAuth2":{"description":"Use a Descope-issued OAuth access token minted for the Grep Public API v2 resource.","flows":{"authorizationCode":{"authorizationUrl":"https://api.descope.com/oauth2/v1/apps/authorize","scopes":{"billing:read":"Read billing and usage information.","research:read":"Read research jobs, reports, files, timelines, quota, and usage.","research:write":"Start research and manage research attachments."},"tokenUrl":"https://api.descope.com/oauth2/v1/apps/token"},"clientCredentials":{"scopes":{"billing:read":"Read billing and usage information.","research:read":"Read research resources.","research:write":"Create research resources."},"tokenUrl":"https://api.descope.com/oauth2/v1/apps/token"}},"type":"oauth2"}}},"info":{"description":"Programmatic access to Grep — kick off research jobs, fetch their reports and files, and check your credit balance. All endpoints accept either a UUID or a slug for ``{job_id_or_slug}``.","title":"Grep API","version":"1.0"},"openapi":"3.1.0","paths":{"/api/v2/a2a":{"post":{"description":"A2A JSON-RPC endpoint for Grep research tasks.","operationId":"a2a_jsonrpc_api_v2_a2a_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"title":"Envelope","type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"A2A Jsonrpc","tags":["Agent-to-Agent"]}},"/api/v2/attachments":{"post":{"description":"Upload files and receive an ``attachment_id`` for ``POST /research``.\n\nThe upload is independent of any job. Pass the returned\n``attachment_id`` in ``attachment_ids`` when creating research and\nthe server will copy these files into that job's ``./input_files/``.","operationId":"create_research_attachment_v2","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_research_attachment_v2"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchAttachmentResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Create Research Attachment","tags":["Attachments"]}},"/api/v2/attachments/{attachment_id}":{"delete":{"description":"Delete an attachment so it cannot be used by future jobs.","operationId":"delete_research_attachment_v2","parameters":[{"in":"path","name":"attachment_id","required":true,"schema":{"format":"uuid","title":"Attachment Id","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchAttachmentDeleteResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Delete Research Attachment","tags":["Attachments"]},"get":{"description":"Return attachment metadata for the authenticated owner.","operationId":"get_research_attachment_v2","parameters":[{"in":"path","name":"attachment_id","required":true,"schema":{"format":"uuid","title":"Attachment Id","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchAttachmentResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"Get Research Attachment","tags":["Attachments"]}},"/api/v2/billing/transactions":{"get":{"description":"List the caller's wallet transactions, newest first.\n\nCursor-paginated. Each entry has the transaction type\n(``deposit``, ``consumption``, ``bonus``, ``refund``,\n``expiration``, ``auto_topup``), credit amount, balance after,\noptional ``job_id`` for consumption tied to a research job, and\nStripe metadata for paid deposits.","operationId":"get_billing_transactions_v2","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor.","title":"Cursor"}},{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":100,"minimum":1,"title":"Limit","type":"integer"}},{"description":"Filter to a single transaction type.","in":"query","name":"type","required":false,"schema":{"anyOf":[{"enum":["deposit","consumption","bonus_consumption","base_consumption","refund","expiration","auto_topup"],"type":"string"},{"type":"null"}],"description":"Filter to a single transaction type.","title":"Type"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPage_BillingTransactionItem_"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["billing:read"]}],"summary":"Get Billing Transactions","tags":["Billing"]}},"/api/v2/billing/usage":{"get":{"description":"Aggregate credit spend over the requested period.\n\nReturns total credits used, dollars spent (paid credits only —\nbonus credits are excluded from the cents fields), per-effort\nbreakdown, and a projection of where the period will end at\ncurrent burn rate. Defaults to the current billing period;\npass ``period=last_30d`` for a rolling 30-day window or\n``period=custom`` with ``from`` + ``to`` for an explicit range.","operationId":"get_billing_usage_v2","parameters":[{"description":"Aggregation window. ``custom`` requires ``from`` and ``to``.","in":"query","name":"period","required":false,"schema":{"default":"current_billing","description":"Aggregation window. ``custom`` requires ``from`` and ``to``.","enum":["current_billing","last_30d","custom"],"title":"Period","type":"string"}},{"description":"Custom-period lower bound (ISO 8601).","in":"query","name":"from","required":false,"schema":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"Custom-period lower bound (ISO 8601).","title":"From"}},{"description":"Custom-period upper bound (ISO 8601).","in":"query","name":"to","required":false,"schema":{"anyOf":[{"format":"date-time","type":"string"},{"type":"null"}],"description":"Custom-period upper bound (ISO 8601).","title":"To"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingUsageResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["billing:read"]}],"summary":"Get Billing Usage","tags":["Billing"]}},"/api/v2/experts":{"get":{"description":"Returns the canonical list of public research experts that v2 and the MPP gateway both accept on the ``expert_id`` field. Use this to pick an ``expert_id`` for ``POST /api/v2/research``. Public — no auth required.","operationId":"list_experts_v2","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExpertSummary"},"title":"Response List Experts V2","type":"array"}}},"description":"Successful Response"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"List public research experts","tags":["Experts"]}},"/api/v2/quota":{"get":{"description":"Current quota for the authenticated caller.\n\nReturns the caller's subscription tier, remaining credits, and the\ncost in credits of each effort tier. To answer \"will my next call\nsucceed?\", compare ``credits_remaining`` against\n``credits_required_for_effort[<effort>]`` — or use\n``GET /quota/check?effort=<effort>`` for the same check in one\ncall.","operationId":"get_quota_v2","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaResponse"}}},"description":"Successful Response"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["billing:read"]}],"summary":"Get Quota","tags":["Billing"]}},"/api/v2/quota/check":{"get":{"description":"Non-consuming quota check for a specific effort tier.\n\nReturns whether the caller has enough credits to run ``POST\n/research`` at the requested ``effort`` without actually starting\na job. Use this to gate UX (disable a \"Run\" button when the\nresponse says ``allowed=false``) instead of catching a 402 after\nsubmitting.","operationId":"check_quota_v2","parameters":[{"description":"Effort tier to pre-flight. Accepts the four public tiers (``low``, ``medium``, ``high``, ``build``) and the legacy aliases (``ultra_fast``, ``deep``, ``ultra_deep``) — same values the create endpoint accepts. The response echoes the value you sent.","in":"query","name":"effort","required":true,"schema":{"description":"Effort tier to pre-flight. Accepts the four public tiers (``low``, ``medium``, ``high``, ``build``) and the legacy aliases (``ultra_fast``, ``deep``, ``ultra_deep``) — same values the create endpoint accepts. The response echoes the value you sent.","enum":["low","medium","high","build","ultra_fast","deep","ultra_deep"],"title":"Effort","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaCheckResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["billing:read"]}],"summary":"Check Quota","tags":["Billing"]}},"/api/v2/research":{"get":{"description":"List the caller's research jobs, newest first.\n\nCursor-paginated. Each row carries the minimum needed to render a\nlist and link to the detail view: ``job_id``, ``slug``, ``status``,\n``question``, ``effort``, and timestamps. Use ``GET\n/research/{job_id_or_slug}`` to fetch the full job — including the\nrendered report and revision history — for any row you want to\ninspect.","operationId":"list_research_jobs_v2","parameters":[{"description":"Opaque pagination cursor.","in":"query","name":"cursor","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor.","title":"Cursor"}},{"in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":100,"minimum":1,"title":"Limit","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPage_ResearchJobListItem_"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"List Research Jobs","tags":["Research"]},"post":{"description":"Start a research job.","operationId":"create_research_job_v2","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchJobCreate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchJobResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Create Research Job","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}":{"get":{"description":"Fetch a single research job by UUID or slug.\n\nReturns identity, lifecycle status, original request echo, timing\nmetadata, the rendered Markdown report (for completed jobs), and\nthe list of published revisions. The path parameter accepts either\na UUID or a human-readable slug.\n\nPass ``?revision=<sha>`` to read the report at a specific commit;\notherwise the latest report is returned.","operationId":"get_research_job_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}},{"description":"Optional commit SHA. When set, ``report.markdown`` is read from that revision instead of the current report. Use a ``commit_sha`` from the ``revisions`` array of an earlier call. ``404 revision_not_found`` if the SHA doesn't exist for this job.","in":"query","name":"revision","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional commit SHA. When set, ``report.markdown`` is read from that revision instead of the current report. Use a ``commit_sha`` from the ``revisions`` array of an earlier call. ``404 revision_not_found`` if the SHA doesn't exist for this job.","title":"Revision"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchJobDetail"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"Get Research Job With Auth Context","tags":["Research"]},"patch":{"description":"Update mutable fields on a research job.\n\nCurrently only ``is_public`` is mutable. Set it to ``true`` to make\nthe job publicly viewable without authentication (the report,\nfiles, and timeline become readable via capability mode); set it\nto ``false`` to revert to owner/admin-only access.\n\nOnly the job's owner or a Parcha admin can change visibility.\nLocked jobs (content moderation) reject the call.","operationId":"update_research_job_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchVisibilityUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchVisibilityResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Update Research Job","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}/cancel":{"post":{"description":"Cancel a queued or running research job.\n\nCancellation is terminal. The job status becomes ``cancelled`` and\nrunning check results are marked ``interrupted``. Repeating the call\nfor a terminal job is safe and returns the current terminal status.","operationId":"cancel_research_job_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchCancelResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Cancel Research Job Endpoint","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}/continue":{"post":{"description":"Continue a completed research job in place.\n\nOnly successfully completed jobs can be continued. Active, paused,\nfailed, locked, and cancelled jobs return ``409`` with a stable\nmachine-readable error code.\n\nREST keeps the same Grep job id/slug and adds a new continuation\ncheck result. A2A uses this same service but returns the\ncontinuation check result as a new A2A task id so terminal A2A\ntasks are not restarted.","operationId":"continue_research_job_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchContinuationCreate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchContinuationResponse"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:write"]}],"summary":"Continue Research Job Endpoint","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}/files":{"get":{"description":"List files in a research job's workspace.\n\nReturns every file the agent produced or modified during the run,\nwith sizes, MIME types, and last-commit timestamps. Use ``GET\n/research/{job_id_or_slug}/files/{file_path}`` to download individual\nfile contents.","operationId":"list_research_files_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchFilesList"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"List Research Files","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}/files/{file_path}":{"get":{"description":"Download a single file from a research job's workspace.\n\nReturns the raw file bytes with a matching ``Content-Type``\nheader. ``file_path`` is the slash-separated path from any entry\nin the ``GET /research/{job_id_or_slug}/files`` listing.","operationId":"read_research_file_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}},{"in":"path","name":"file_path","required":true,"schema":{"title":"File Path","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"Read Research File","tags":["Research"]}},"/api/v2/research/{job_id_or_slug}/timeline":{"get":{"description":"Paginated, recent-first execution timeline for a research job.\n\nReturns the events the agent emitted while working on the job —\ntool calls, sub-agent progress, thinking traces, text outputs.\nNewest first; walk older pages with the returned ``next_cursor``.\n\nEach event is a flat projection of the internal status-message\nlog (see ``TimelineEvent``). The full SDK content shape is\nintentionally not exposed; secrets, raw shell commands, and\ncost/token fields are stripped or redacted before the response\nis built.\n\nUse this to drive a \"what's the agent doing right now?\" UI by\npolling every few seconds while ``status`` is ``in_progress``.","operationId":"get_research_timeline_v2","parameters":[{"in":"path","name":"job_id_or_slug","required":true,"schema":{"title":"Job Id Or Slug","type":"string"}},{"description":"Opaque cursor from a previous response's ``next_cursor`` field.","in":"query","name":"cursor","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor from a previous response's ``next_cursor`` field.","title":"Cursor"}},{"description":"Maximum number of events to return per page (default 50, max 200).","in":"query","name":"limit","required":false,"schema":{"default":50,"description":"Maximum number of events to return per page (default 50, max 200).","maximum":200,"minimum":1,"title":"Limit","type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPage_TimelineEvent_"}}},"description":"Successful Response"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}},"description":"Validation Error"}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"summary":"Get Research Timeline With Auth Context","tags":["Research"]}}},"security":[{"GrepApiKeyBearer":[]},{"GrepOAuth2":["research:read"]}],"tags":[{"name":"Research"},{"name":"Attachments"},{"name":"Billing"},{"name":"Agent-to-Agent"}]}