Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.manticscore.com/llms.txt

Use this file to discover all available pages before exploring further.

The Research API runs a five-stage pipeline — interpret, search, judge, analyze, synthesize — and returns results via cursor-resumable NDJSON streams. You can start a standalone research job and optionally attach it to a project, or use POST /projects/research to do both atomically. Every POST /research call returns immediately; the pipeline runs in the background and you consume progress through the events endpoint.

Start research

idea
string
required
The product idea or question to research. Maximum 5,000 characters.
project_id
string
UUID of an existing project to attach the research to. Pass null to create unattached research.
mode
string
default:"market"
Pipeline mode. Use market for a full competitive landscape analysis. Use feature to focus on feature analysis — this automatically chains into feature deep research on the top 5 features after the market research completes.
The rate limit is 10 requests per minute. If you’re rate-limited with a valid session token, ManticScore queues the request automatically (up to 5 per user) and retries it when capacity is available — you don’t need to retry manually.
curl -X POST https://api.manticscore.com/research \
  -H "Authorization: Bearer <token>" \
  -H "Idempotency-Key: idea-v1-2026-04-19" \
  -H "Content-Type: application/json" \
  -d '{"idea": "AI expense tracker for freelancers", "project_id": "9f4e2a1b-...", "mode": "market"}'
{
  "job_id": "7c3d1e9a-...",
  "status": "queued",
  "position": 0
}
The job is queued. Stream progress from GET /research/{job_id}/events.
A 409 means an identical request is already running. A 429 means you’ve hit the rate limit — if using a session token, your request may have been captured to the retry queue.

Stream research events

Subscribe to the live NDJSON stream for a research job. The cursor parameter lets you resume from any point — the server replays all events since that sequence number before switching to live delivery.
cursor
number
default:"0"
Sequence number to resume from. Use 0 to start from the beginning.
curl -N "https://api.manticscore.com/research/7c3d1e9a-.../events?cursor=0" \
  -H "Authorization: Bearer <token>"
Each line is a JSON object with shape {"v": 1, "event": "<type>", "data": {...}}. The event types are:
EventDescription
stream_startConnection confirmed. Contains request_id and job_id.
stageA pipeline stage started, completed, or failed. See stage names below.
progressFree-text progress message within a stage.
retryA stage is being retried. Contains attempt number and source.
resultResearch completed. Contains the full research artifact.
errorA fatal error occurred. Contains message, code, and retryable.
doneStream is closed. Always the last event.
Pipeline stage names: interpret, search, judge, analyze, synthesize, persist.
The judge stage runs between search and analyze when retrieval quality scoring is enabled. It is non-blocking — if it fails, the pipeline continues to analyze regardless.
Auto-seeded build graph on completion. When research finishes with a quality score of 70 or higher and the attached project has no existing build graph, the server automatically creates a draft build graph seeded with the top 5 features from the research. The graph is created with status: "ready" and source: "research_auto_seeded" and emits its events on the build channel. Lower-quality research (< 70) and projects that already have a graph are skipped — you can still create one manually via POST /build-graphs. This is a fire-and-forget hook; if it fails the research result is not affected.
Parse on the event field and ignore unknown types. New event types may be added without a version bump.

Get research status

Returns the current status and the last event sequence number without opening a stream.
curl "https://api.manticscore.com/research/7c3d1e9a-.../status" \
  -H "Authorization: Bearer <token>"
200 response
{
  "job_id": "7c3d1e9a-...",
  "status": "running",
  "last_event_seq": 15,
  "error": null
}
status
string
required
One of queued, running, completed, failed.
last_event_seq
number
required
Use this as the cursor value when reconnecting to the events stream to avoid replaying events you’ve already processed.
error
object
Present only when status is failed. Contains code, message, and retryable.Common research error codes:
  • EMPTY_OUTPUT — The pipeline ran end-to-end, gathered no supporting evidence, and produced zero incumbents, zero emerging players, and zero features. This typically means the submitted idea was a meta-description, gibberish, or too narrow to research. Returned with retryable: false — re-running the same input will produce the same result. Surface the message to the user and prompt them to submit a more specific product idea.
  • MODEL_EMPTY_DESPITE_EVIDENCE — The pipeline collected supporting evidence but the model still returned zero incumbents, zero emerging players, and zero features (and a strict-mode retry also returned empty). This is distinct from EMPTY_OUTPUT: the input was researchable, but the model failed to extract structured competitors from the source material. Returned with retryable: false. Surface the message and suggest the user rephrase the idea as a specific product or feature.
  • EMPTY_INPUT — The submitted idea was rejected before the pipeline ran (for example, missing or whitespace-only body text). Returned with retryable: false.
Both EMPTY_OUTPUT and MODEL_EMPTY_DESPITE_EVIDENCE errors include an evidence_count field on the error payload reporting how many sources the pipeline gathered before the analyze stage failed.

List queued retries

Returns the authenticated user’s pending DLQ rows — research requests that hit the rate limit and were captured for later replay. iOS surfaces this list as “you have N queued retries”. Items expire silently after 24 hours. Rate limit: 30 requests per minute.
curl https://api.manticscore.com/research/queued \
  -H "Authorization: Bearer <token>"
200 response
{
  "count": 2,
  "items": [
    {
      "id": "8d2f1c4b-...",
      "idea": "AI expense tracker for freelancers",
      "project_id": "9f4e2a1b-...",
      "mode": "market",
      "queued_at": "2026-04-26T09:31:12Z"
    },
    {
      "id": "0a1c8e5d-...",
      "idea": "Voice-controlled task manager",
      "project_id": null,
      "mode": "feature",
      "queued_at": "2026-04-26T10:14:48Z"
    }
  ]
}
count
number
required
Number of pending entries returned. Capped to entries created within the last 24 hours.
items
array
required
Pending items are replayed automatically when capacity frees up — this endpoint is read-only and exists so clients can show a “queued retries” badge to the user.

Attach research to a project

Associates an existing research job with a project. Useful if you started research without a project_id and want to link it after the fact.
project_id
string
required
UUID of the project to attach this research job to.
curl -X PATCH "https://api.manticscore.com/research/7c3d1e9a-..." \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"project_id": "9f4e2a1b-..."}'
200 response
{
  "job_id": "7c3d1e9a-...",
  "project_id": "9f4e2a1b-..."
}

Diff research versions

Compare the current research version against the previous one to see what changed between runs.
curl "https://api.manticscore.com/research/7c3d1e9a-.../diff" \
  -H "Authorization: Bearer <token>"
200 response
{
  "diff_available": true,
  "current_version": 2,
  "previous_version": 1,
  "competitors": {
    "added": ["Fyle"],
    "removed": [],
    "unchanged": 3
  },
  "features": {
    "added": ["GPS mileage tracking"],
    "removed": ["Manual entry mode"],
    "unchanged": 5
  },
  "recommendation_changed": false
}
If no previous version exists: {"diff_available": false, "reason": "No previous version to compare against"}.

Remix: get adjacent ideas

Generates three pivot ideas related to the completed research. Each suggestion includes a rationale and an explanation of how it differentiates from the original idea.
curl -X POST "https://api.manticscore.com/research/7c3d1e9a-.../remix" \
  -H "Authorization: Bearer <token>"
200 response
{
  "suggestions": [
    {
      "idea": "AI mileage tracker for gig workers",
      "rationale": "Gig workers have higher mileage deduction complexity than freelancers.",
      "differentiation": "Focuses on vehicle tax deductions rather than receipt capture."
    }
  ]
}

Control visibility (reuse scope)

Set whether your research can be used as a cache source for other users. user means only you can reuse it; public makes it available to the global cache.

Update one job

reuse_scope
string
required
Either user (private) or public.
curl -X PATCH "https://api.manticscore.com/research/7c3d1e9a-.../scope" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"reuse_scope": "public"}'

Update all completed research at once

curl -X POST https://api.manticscore.com/research/scope/bulk \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"reuse_scope": "public"}'
200 response
{"updated": 5}

Share research publicly

Creates a public share link for a completed research job. The link is served as an App Clip page at manticscore.com/clip/research-....
curl -X POST "https://api.manticscore.com/research/7c3d1e9a-.../share" \
  -H "Authorization: Bearer <token>"
200 response
{
  "share_token": "abc123xyz",
  "share_url": "https://manticscore.com/clip/research-abc123xyz",
  "expires_at": "2026-05-19T10:00:00Z"
}
Returns 400 if the research is not yet completed.

Read shared research (public)

Anyone with the share token can read the research without authentication.
curl "https://api.manticscore.com/research/shared/abc123xyz" \
  -H "Accept: application/json"
By default the endpoint returns HTML. Pass Accept: application/json to get the JSON response.
curl -X DELETE "https://api.manticscore.com/research/7c3d1e9a-.../share" \
  -H "Authorization: Bearer <token>"
200 response
{"revoked": true}

Analyze a competitor feature

Reverse-engineers a specific feature from a named competitor. Returns a structured analysis covering UX flow, technical approach, implementation challenges, open-source alternatives, and a build estimate. Rate limit: 5 requests per minute.
company
string
required
The competitor’s name. Maximum 200 characters.
feature
string
required
The feature to analyze. Maximum 500 characters.
context
string
Additional context about your own product or constraints. Maximum 2,000 characters.
project_id
string
Optional project UUID to scope the analysis.
curl -X POST https://api.manticscore.com/research/feature-analysis \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "company": "Expensify",
    "feature": "SmartScan OCR receipt capture",
    "context": "Building for freelancers who need to track deductible expenses",
    "project_id": "9f4e2a1b-..."
  }'
Returns a structured analysis object. The exact shape depends on the feature, but always includes UX flow, technical approach, known challenges, OSS alternatives, and a build time estimate.

Export to PDF

Downloads a completed research job as a binary PDF file. The export is rendered from the same job artifacts shown in the app — interpretation, incumbents, emerging players, features, white spaces, and signals — and is scoped to the authenticated user. If WeasyPrint is unavailable on the server, the endpoint falls back to a plain-text export.
format
string
default:"pdf"
Export format. Currently only pdf is supported.
curl "https://api.manticscore.com/research/7c3d1e9a-.../export?format=pdf" \
  -H "Authorization: Bearer <token>" \
  --output research.pdf
The response is binary content with Content-Type: application/pdf and a Content-Disposition: attachment header naming the file <idea>-research.pdf. The PDF includes the research title, creation timestamp, and a Quality: <score>/100 badge when a quality score is available.
StatusMeaning
200PDF (or text/plain fallback) returned.
404Research job not found, owned by another user, or not in completed status.
422Unsupported format value.