Skip to content

Start a report

POST
/v1/reports
curl --request POST \
--url https://api.recomention.com/v1/reports \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "domain": "example", "description": "example", "category": "example", "brand": "example", "plan": "QUICK", "seedPrompts": [ "example" ], "engines": [ "OPENAI" ], "funding": "credits", "providerKeys": { "OPENAI": "example", "ANTHROPIC": "example", "PERPLEXITY": "example", "GEMINI": "example", "GROK": "example", "AI_OVERVIEW": "example" }, "idempotencyKey": "example" }'

Spends an agency credit, or runs on your own provider keys where enabled. Starts are limited to 10 per key per hour on top of the per-minute limit, and, on your own keys, to the Agent plan’s limits.

Idempotency. Send an Idempotency-Key header (or body idempotencyKey, 16–128 of A–Z a–z 0–9 - _). Keys are scoped to the account that owns the API key, not to the key itself or globally, and bound to the report it describes: domain, brand, description, category, plan, engines and seedPrompts (the same key with any of those changed is a different start). providerKeys are not part of that fingerprint: a retry with the same key and corrected provider keys returns the original start, even a failed one, so rerun with a new Idempotency-Key. A retry with the same key and the same report fields returns the original start (200, reused: true) and spends nothing again. If that original start was funded by a credit that has since been returned (it could not be queued, or it started, failed and got its credit back), the retry gets 409; start again with a new key. Without a key every request is a new start.

A 503 from this operation is ambiguous. The start may still complete after the response (for example when it times out on our side). Retry with the same Idempotency-Key and body: you get the original start if it went through, or a new one if it did not, never both.

Idempotency-Key
string
/^[A-Za-z0-9_-]{16,128}$/

Makes a start safe to retry. Scoped to the account that owns the API key and to the report fields (not providerKeys); a retry must repeat them. Same rules as body idempotencyKey; if both are sent they must match.

Media typeapplication/json
object
domain
required

The product’s domain, e.g. example.com.

string
>= 3 characters <= 253 characters
description
required

One line on what the product does.

string
>= 3 characters <= 300 characters
category
required

The category buyers would search, e.g. “meeting scheduling”.

string
>= 2 characters <= 120 characters
brand

The product’s name. Derived from the domain when omitted.

string
<= 80 characters
plan

Which plan’s question count and engines to run. An agency credit runs FULL.

string
default: FULL
Allowed values: QUICK FULL DEEP
seedPrompts

Buyer questions to ask. They must not name the product.

Array<string>
<= 40 items
engines

A subset of the plan’s engines. Defaults to all of them.

Array<string>
>= 1 items <= 6 items
Allowed values: OPENAI ANTHROPIC PERPLEXITY GEMINI GROK AI_OVERVIEW
funding
required

“credits” spends one agency credit; “byok” runs on your own provider keys where enabled.

string
Allowed values: credits byok
providerKeys

Funding “byok” only. Used for this run and never stored in the clear or echoed back.

object
OPENAI
string
<= 400 characters
ANTHROPIC
string
<= 400 characters
PERPLEXITY
string
<= 400 characters
GEMINI
string
<= 400 characters
GROK
string
<= 400 characters
AI_OVERVIEW
string
<= 400 characters
idempotencyKey

Same as the Idempotency-Key header. A retry with the same key returns the first start.

string
/^[A-Za-z0-9_-]{16,128}$/

An earlier start with the same idempotency key (reused: true).

Media typeapplication/json
object
slug
required
string
status
required
string
reused
required

True when an earlier start with the same idempotency key is returned (200).

boolean
funding
required
string
Allowed values: credits byok
url
required
string
statusUrl
required

Poll this about once a minute.

string

Example

{
"funding": "credits"
}

Started. Poll statusUrl.

Media typeapplication/json
object
slug
required
string
status
required
string
reused
required

True when an earlier start with the same idempotency key is returned (200).

boolean
funding
required
string
Allowed values: credits byok
url
required
string
statusUrl
required

Poll this about once a minute.

string

Example

{
"funding": "credits"
}

The request is invalid. fields names what to fix.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

Missing, malformed, unknown or revoked API key.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

No agency credit left, or (own keys) no active Agent plan (limit: "plan").

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

Not allowed for this account or report.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

The idempotency key belongs to a credit start whose credit was refunded, whether it could not be queued or it ran and failed (start again with a new key), or another conflict named in error.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

Body larger than 32 KB.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}

Rate limited (per key, per address, or 10 starts per key per hour), or an Agent plan limit named in limit. perDay (starts in any 24 hours), reportsPerMonth and projects (per billing period) carry Retry-After and retryAfterSeconds when the wait is known. concurrent carries neither: it frees when a running report finishes, so poll its status and retry then.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}
Retry-After
integer

Seconds to wait.

RateLimit-Limit
integer

Requests allowed in the window.

RateLimit-Remaining
integer

Requests left in the window (0 on a 429).

RateLimit-Reset
integer

Seconds until the window resets.

Ambiguous: the start may or may not have happened. Retry after Retry-After seconds with the same Idempotency-Key and body; it never spends twice.

Media typeapplication/json
object
error
required

What went wrong, in plain words. Never repeats a submitted secret.

string
fields

Request fields to fix (400).

Array<string>
retryAfterSeconds

Seconds to wait before retrying (429).

integer
>= -9007199254740991 <= 9007199254740991
limit

Which plan limit refused a start: plan, projects, reportsPerMonth, perDay, concurrent.

string
status

The report’s status, when it explains the refusal (409).

string

Example generated

{
"error": "example",
"fields": [
"example"
],
"retryAfterSeconds": 1,
"limit": "example",
"status": "example"
}
Retry-After
integer

Seconds to wait.