Discovery: 13 operations (discovery.balance, discovery.handles.resolve, discovery.icp_profiles.list, discovery.modes, discovery.quote, discovery.recipes.create, discovery.runs.list, discovery.runs.create, discovery.runs.get, discovery.runs.cancel, discovery.candidates.list, discovery.runs.preview_decision, discovery.candidates.promote).
GET /v1/discovery/balance
The organization's discovery token balance.
Tokens the organization can spend now (plan and purchased), tokens held by its runs that are still moving, and when the plan period ends. Shared by every workspace of the organization.
Operation id discovery.balanceScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Field Type Required Description available_tokensintegeryes -9007199254740991 to 9007199254740991 period_ends_atstring | nullyes reserved_tokensintegeryes -9007199254740991 to 9007199254740991
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/balance" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"available_tokens": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reserved_tokens": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"period_ends_at": {
"type": [
"string",
"null"
]
}
},
"required": [
"available_tokens",
"reserved_tokens",
"period_ends_at"
],
"additionalProperties": false
}POST /v1/discovery/handles/resolve
Resolve Instagram handles to accounts, to use as a recipe's seeds.
Up to ten handles per request. The answer does not say whether a handle was already known or looked up; a lookup may spend from the platform's vendor budget, which is why the scope is discovery:spend.
Field Type Required Description handlesstring[]yes 1 to 10 items
Field Type Required Description resultsobject[]yes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/handles/resolve" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"handles": [
"string"
]
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"handles": {
"minItems": 1,
"maxItems": 10,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
}
},
"required": [
"handles"
]
}Response 200 Copy
{
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"handle": {
"type": "string"
},
"ig_user_id": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"found",
"not_found",
"private",
"unavailable",
"invalid"
]
}
},
"required": [
"handle",
"ig_user_id",
"status"
],
"additionalProperties": false
}
}
},
"required": [
"results"
],
"additionalProperties": false
}GET /v1/discovery/icp-profiles
The organization's customer profiles (ICP), each at its newest version.
Name a profile and version in a recipe's qualify step to judge the run's accounts against it.
Operation id discovery.icp_profiles.listScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Field Type Required Description dataobject[]yes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/icp-profiles" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"version": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"version"
],
"additionalProperties": false
}
}
},
"required": [
"data"
],
"additionalProperties": false
}GET /v1/discovery/modes
The discovery modes and what this deployment can run.
The mode catalog (rate per result, quote shape, availability) and the deployment's capabilities.
Operation id discovery.modesScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Field Type Required Description capabilitiesobjectyes modesobject[]yes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/modes" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"modes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"family": {
"type": "string"
},
"ratePerResult": {
"type": "number"
},
"quoteShape": {
"type": "string"
},
"available": {
"type": "boolean"
},
"deployable": {
"type": "boolean"
}
},
"required": [
"id",
"family",
"ratePerResult",
"quoteShape",
"available",
"deployable"
],
"additionalProperties": {}
}
},
"capabilities": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"modes",
"capabilities"
],
"additionalProperties": {}
}POST /v1/discovery/quote
Price a recipe in tokens without saving or starting anything.
Nothing is written, reserved or bought. Counts against the organization's daily budget of quotes (1 000 a day, shared with every response of POST /v1/discovery/runs that carries a quote).
Operation id discovery.quoteScopes discovery:readRate class `discovery_quote` , plus dq_dayIdempotency Not applicable Keys Developer keys
Field Type Required Description docobjectyes A search recipe document ( { v: 1, steps: [...] }), as the app's recipe builder saves it.
Field Type Required Description modestring | nullyes quoteobjectyes The price of a recipe in tokens (the app's Quote). refusalobject | nullyes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/quote" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"doc": {
"v": 1,
"steps": [
{
"type": "seed",
"id": "s",
"igUserIds": [
"25025320"
]
},
{
"type": "expand",
"id": "e",
"in": "s",
"edge": "following",
"limit": 100
},
{
"type": "rank",
"id": "r",
"in": "e",
"by": "score",
"take": 50
}
]
}
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"doc": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "A search recipe document (`{ v: 1, steps: [...] }`), as the app's recipe builder saves it."
}
},
"required": [
"doc"
]
}Response 200 Copy
{
"type": "object",
"properties": {
"quote": {
"type": "object",
"properties": {
"shape": {
"type": "string",
"enum": [
"exact",
"ceiling",
"range"
]
},
"tokensMin": {
"type": "number"
},
"tokensMax": {
"type": "number"
},
"expectedResultsMin": {
"type": [
"number",
"null"
]
},
"expectedResultsMax": {
"type": [
"number",
"null"
]
},
"estimatedSeconds": {
"type": "number"
},
"seedCount": {
"type": "number"
},
"seedAudienceTotal": {
"type": "number"
},
"lowYield": {
"type": "boolean"
},
"refundThreshold": {
"type": [
"number",
"null"
]
},
"blockedReason": {
"anyOf": [
{
"type": "string",
"enum": [
"spend_ceiling",
"invalid_recipe"
]
},
{
"type": "null"
}
]
}
},
"required": [
"shape",
"tokensMin",
"tokensMax",
"expectedResultsMin",
"expectedResultsMax",
"estimatedSeconds",
"seedCount",
"seedAudienceTotal",
"lowYield",
"refundThreshold",
"blockedReason"
],
"additionalProperties": {},
"description": "The price of a recipe in tokens (the app's Quote)."
},
"mode": {
"type": [
"string",
"null"
]
},
"refusal": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"code",
"message",
"path"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"quote",
"mode",
"refusal"
],
"additionalProperties": {}
}POST /v1/discovery/recipes
Save a search recipe.
Recipes are saved once per organization per canonical document: saving the same search again answers 200 with the first save's id and name instead of 201.
Operation id discovery.recipes.createScopes discovery:spendRate class `write` Idempotency `Idempotency-Key` accepted Keys Developer keys
Field Type Required Description docobjectyes A search recipe document ( { v: 1, steps: [...] }), as the app's recipe builder saves it. namestringyes
Field Type Required Description hashstringyes idstringyes namestringyes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/recipes" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Fitness coaches PL",
"doc": {
"v": 1,
"steps": [
{
"type": "seed",
"id": "s",
"igUserIds": [
"25025320"
]
},
{
"type": "expand",
"id": "e",
"in": "s",
"edge": "following",
"limit": 100
},
{
"type": "rank",
"id": "r",
"in": "e",
"by": "score",
"take": 50
}
]
}
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"doc": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "A search recipe document (`{ v: 1, steps: [...] }`), as the app's recipe builder saves it."
}
},
"required": [
"name",
"doc"
]
}Response 201 Copy
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"hash": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"hash",
"name"
],
"additionalProperties": false
}GET /v1/discovery/runs
The workspace's runs, newest first.
Operation id discovery.runs.listScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Name Type Required Description state"queued" | "running" | "awaiting_preview" | "partial" | "done" | "cancelled" | "failed"no created_afterdate-timeno limitintegerno 1 to 50, default 20 cursorstringno 1 to 2048 characters
Field Type Required Description dataobject[]yes has_morebooleanyes next_cursorstring | nullyes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/runs" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"mode": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"queued",
"running",
"awaiting_preview",
"partial",
"done",
"cancelled",
"failed"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "number"
},
"total": {
"type": "number"
},
"step": {
"type": "string"
}
},
"required": [
"done",
"total",
"step"
],
"additionalProperties": false
},
"startedAt": {
"type": "string"
},
"etaSeconds": {
"type": [
"number",
"null"
]
},
"candidatesReady": {
"type": "number"
},
"matchedTotal": {
"type": "number"
},
"paidFor": {
"type": "number"
},
"family": {
"type": "string"
},
"previewReady": {
"type": "boolean"
},
"previewDecision": {
"anyOf": [
{
"type": "string",
"enum": [
"pending",
"continue",
"stopped"
]
},
{
"type": "null"
}
]
},
"skippedSources": {
"type": "number"
},
"queuedBehind": {
"anyOf": [
{
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"label": {
"type": "string"
},
"etaAt": {
"type": "string"
}
},
"required": [
"runId",
"label",
"etaAt"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"mode",
"state",
"progress",
"startedAt",
"etaSeconds",
"candidatesReady",
"matchedTotal",
"paidFor",
"family",
"previewReady",
"previewDecision",
"skippedSources",
"queuedBehind"
],
"additionalProperties": {},
"description": "One discovery run (the app's Run). The single-run read adds `activity` and, where the mode has one, `graph`, `likers` or `search`; the list adds `searchSummary`, `tokens` and `promotedCount`."
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"has_more",
"next_cursor"
],
"additionalProperties": false
}POST /v1/discovery/runs
Start a discovery run: price the recipe, reserve its tokens and queue it.
Send recipe_id (a saved recipe) or recipe ( { name, doc }, saved first, then started), not both. A refusal that is a price (402) carries the quote. Every request counts against the organization's daily budget of quotes, the one POST /v1/discovery/quote spends, and a spent budget answers 429 before anything is priced. Requires an Idempotency-Key: a retry with the same key never starts a second run.
Field Type Required Description recipeobjectno recipe_iduuidno
Field Type Required Description quoteobject | nullyes Null only on an idempotent replay, which rebuilds the run from its id. reserved_tokensintegeryes -9007199254740991 to 9007199254740991 runobjectyes One discovery run (the app's Run). The single-run read adds activity and, where the mode has one, graph, likers or search; the list adds searchSummary, tokens and promotedCount.
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/runs" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"recipe": {
"name": "Fitness coaches PL",
"doc": {
"v": 1,
"steps": [
{
"type": "seed",
"id": "s",
"igUserIds": [
"25025320"
]
},
{
"type": "expand",
"id": "e",
"in": "s",
"edge": "following",
"limit": 100
},
{
"type": "rank",
"id": "r",
"in": "e",
"by": "score",
"take": 50
}
]
}
}
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"recipe_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"recipe": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"doc": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "A search recipe document (`{ v: 1, steps: [...] }`), as the app's recipe builder saves it."
}
},
"required": [
"name",
"doc"
]
}
}
}Response 201 Copy
{
"type": "object",
"properties": {
"run": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"mode": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"queued",
"running",
"awaiting_preview",
"partial",
"done",
"cancelled",
"failed"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "number"
},
"total": {
"type": "number"
},
"step": {
"type": "string"
}
},
"required": [
"done",
"total",
"step"
],
"additionalProperties": false
},
"startedAt": {
"type": "string"
},
"etaSeconds": {
"type": [
"number",
"null"
]
},
"candidatesReady": {
"type": "number"
},
"matchedTotal": {
"type": "number"
},
"paidFor": {
"type": "number"
},
"family": {
"type": "string"
},
"previewReady": {
"type": "boolean"
},
"previewDecision": {
"anyOf": [
{
"type": "string",
"enum": [
"pending",
"continue",
"stopped"
]
},
{
"type": "null"
}
]
},
"skippedSources": {
"type": "number"
},
"queuedBehind": {
"anyOf": [
{
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"label": {
"type": "string"
},
"etaAt": {
"type": "string"
}
},
"required": [
"runId",
"label",
"etaAt"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"mode",
"state",
"progress",
"startedAt",
"etaSeconds",
"candidatesReady",
"matchedTotal",
"paidFor",
"family",
"previewReady",
"previewDecision",
"skippedSources",
"queuedBehind"
],
"additionalProperties": {},
"description": "One discovery run (the app's Run). The single-run read adds `activity` and, where the mode has one, `graph`, `likers` or `search`; the list adds `searchSummary`, `tokens` and `promotedCount`."
},
"quote": {
"anyOf": [
{
"type": "object",
"properties": {
"shape": {
"type": "string",
"enum": [
"exact",
"ceiling",
"range"
]
},
"tokensMin": {
"type": "number"
},
"tokensMax": {
"type": "number"
},
"expectedResultsMin": {
"type": [
"number",
"null"
]
},
"expectedResultsMax": {
"type": [
"number",
"null"
]
},
"estimatedSeconds": {
"type": "number"
},
"seedCount": {
"type": "number"
},
"seedAudienceTotal": {
"type": "number"
},
"lowYield": {
"type": "boolean"
},
"refundThreshold": {
"type": [
"number",
"null"
]
},
"blockedReason": {
"anyOf": [
{
"type": "string",
"enum": [
"spend_ceiling",
"invalid_recipe"
]
},
{
"type": "null"
}
]
}
},
"required": [
"shape",
"tokensMin",
"tokensMax",
"expectedResultsMin",
"expectedResultsMax",
"estimatedSeconds",
"seedCount",
"seedAudienceTotal",
"lowYield",
"refundThreshold",
"blockedReason"
],
"additionalProperties": {},
"description": "The price of a recipe in tokens (the app's Quote)."
},
{
"type": "null"
}
],
"description": "Null only on an idempotent replay, which rebuilds the run from its id."
},
"reserved_tokens": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"run",
"quote",
"reserved_tokens"
],
"additionalProperties": false
}GET /v1/discovery/runs/{run_id}
One run, with its live activity. Poll every 10 seconds while it moves.
Operation id discovery.runs.getScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Name Type Required Description run_idstringyes A run id (uuid). An id that is not a run of this workspace answers 404.. 1 to 64 characters
Field Type Required Description candidatesReadynumberyes etaSecondsnumber | nullyes familystringyes idstringyes matchedTotalnumberyes modestringyes paidFornumberyes previewDecision"pending" | "continue" | "stopped" | nullyes previewReadybooleanyes progressobjectyes queuedBehindobject | nullyes skippedSourcesnumberyes startedAtstringyes state"queued" | "running" | "awaiting_preview" | "partial" | "done" | "cancelled" | "failed"yes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/runs/string" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"mode": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"queued",
"running",
"awaiting_preview",
"partial",
"done",
"cancelled",
"failed"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "number"
},
"total": {
"type": "number"
},
"step": {
"type": "string"
}
},
"required": [
"done",
"total",
"step"
],
"additionalProperties": false
},
"startedAt": {
"type": "string"
},
"etaSeconds": {
"type": [
"number",
"null"
]
},
"candidatesReady": {
"type": "number"
},
"matchedTotal": {
"type": "number"
},
"paidFor": {
"type": "number"
},
"family": {
"type": "string"
},
"previewReady": {
"type": "boolean"
},
"previewDecision": {
"anyOf": [
{
"type": "string",
"enum": [
"pending",
"continue",
"stopped"
]
},
{
"type": "null"
}
]
},
"skippedSources": {
"type": "number"
},
"queuedBehind": {
"anyOf": [
{
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"label": {
"type": "string"
},
"etaAt": {
"type": "string"
}
},
"required": [
"runId",
"label",
"etaAt"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"mode",
"state",
"progress",
"startedAt",
"etaSeconds",
"candidatesReady",
"matchedTotal",
"paidFor",
"family",
"previewReady",
"previewDecision",
"skippedSources",
"queuedBehind"
],
"additionalProperties": {},
"description": "One discovery run (the app's Run). The single-run read adds `activity` and, where the mode has one, `graph`, `likers` or `search`; the list adds `searchSummary`, `tokens` and `promotedCount`."
}POST /v1/discovery/runs/{run_id}/cancel
Cancel a run that is still moving and release its unspent tokens.
A run that has already ended answers cancelled: false with its current state.
Operation id discovery.runs.cancelScopes discovery:spendRate class `write` Idempotency `Idempotency-Key` accepted Keys Developer keys Destructive Yes: it removes or stops something that cannot be restored by repeating the call
Name Type Required Description run_idstringyes A run id (uuid). An id that is not a run of this workspace answers 404.. 1 to 64 characters
Field Type Required Description cancelledbooleanyes runobjectyes One discovery run (the app's Run). The single-run read adds activity and, where the mode has one, graph, likers or search; the list adds searchSummary, tokens and promotedCount.
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/runs/string/cancel" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"cancelled": {
"type": "boolean"
},
"run": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"mode": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"queued",
"running",
"awaiting_preview",
"partial",
"done",
"cancelled",
"failed"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "number"
},
"total": {
"type": "number"
},
"step": {
"type": "string"
}
},
"required": [
"done",
"total",
"step"
],
"additionalProperties": false
},
"startedAt": {
"type": "string"
},
"etaSeconds": {
"type": [
"number",
"null"
]
},
"candidatesReady": {
"type": "number"
},
"matchedTotal": {
"type": "number"
},
"paidFor": {
"type": "number"
},
"family": {
"type": "string"
},
"previewReady": {
"type": "boolean"
},
"previewDecision": {
"anyOf": [
{
"type": "string",
"enum": [
"pending",
"continue",
"stopped"
]
},
{
"type": "null"
}
]
},
"skippedSources": {
"type": "number"
},
"queuedBehind": {
"anyOf": [
{
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"label": {
"type": "string"
},
"etaAt": {
"type": "string"
}
},
"required": [
"runId",
"label",
"etaAt"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"mode",
"state",
"progress",
"startedAt",
"etaSeconds",
"candidatesReady",
"matchedTotal",
"paidFor",
"family",
"previewReady",
"previewDecision",
"skippedSources",
"queuedBehind"
],
"additionalProperties": {},
"description": "One discovery run (the app's Run). The single-run read adds `activity` and, where the mode has one, `graph`, `likers` or `search`; the list adds `searchSummary`, `tokens` and `promotedCount`."
}
},
"required": [
"cancelled",
"run"
],
"additionalProperties": false
}GET /v1/discovery/runs/{run_id}/candidates
A run's results, in its delivery order.
Operation id discovery.candidates.listScopes discovery:readRate class `read` Idempotency Not applicable Keys Developer keys
Name Type Required Description run_idstringyes A run id (uuid). An id that is not a run of this workspace answers 404.. 1 to 64 characters
Name Type Required Description limitintegerno 1 to 100, default 50 cursorstringno 1 to 2048 characters
Field Type Required Description dataobject[]yes has_morebooleanyes next_cursorstring | nullyes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl "https://api.dmhero.ai/v1/discovery/runs/string/candidates" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema Response 200 Copy
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"handle": {
"type": "string"
},
"fullName": {
"type": [
"string",
"null"
]
},
"avatarUrl": {
"type": [
"string",
"null"
]
},
"followers": {
"type": [
"number",
"null"
]
},
"following": {
"type": [
"number",
"null"
]
},
"postsCount": {
"type": [
"number",
"null"
]
},
"bioExcerpt": {
"type": [
"string",
"null"
]
},
"category": {
"type": [
"string",
"null"
]
},
"lang": {
"type": [
"string",
"null"
]
},
"websiteDomain": {
"type": [
"string",
"null"
]
},
"seedHits": {
"type": "number"
},
"pathCount": {
"type": "number"
},
"paths": {
"type": "array",
"items": {
"type": "object",
"properties": {
"seedHandle": {
"type": "string"
},
"viaHandle": {
"type": [
"string",
"null"
]
},
"edge": {
"type": "string"
}
},
"required": [
"seedHandle",
"viaHandle",
"edge"
],
"additionalProperties": {}
}
},
"state": {
"type": "string",
"enum": [
"new",
"shortlisted",
"rejected",
"promoted"
]
},
"duplicateOf": {
"anyOf": [
{
"type": "object",
"properties": {
"leadId": {
"type": "string"
},
"since": {
"type": "string"
}
},
"required": [
"leadId",
"since"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"handle",
"fullName",
"avatarUrl",
"followers",
"following",
"postsCount",
"bioExcerpt",
"category",
"lang",
"websiteDomain",
"seedHits",
"pathCount",
"paths",
"state",
"duplicateOf"
],
"additionalProperties": {},
"description": "One result of a run (the app's Candidate), in the run's delivery order. A run that judges against a customer profile adds `verdict`; a local business run adds `local`."
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"has_more",
"next_cursor"
],
"additionalProperties": false
}POST /v1/discovery/runs/{run_id}/preview-decision
Answer a run's preview: continue spending its reservation, or stop and release it.
Operation id discovery.runs.preview_decisionScopes discovery:spendRate class `write` Idempotency `Idempotency-Key` accepted Keys Developer keys
Name Type Required Description run_idstringyes A run id (uuid). An id that is not a run of this workspace answers 404.. 1 to 64 characters
Field Type Required Description decision"continue" | "stop"yes
Field Type Required Description candidatesReadynumberyes etaSecondsnumber | nullyes familystringyes idstringyes matchedTotalnumberyes modestringyes paidFornumberyes previewDecision"pending" | "continue" | "stopped" | nullyes previewReadybooleanyes progressobjectyes queuedBehindobject | nullyes skippedSourcesnumberyes startedAtstringyes state"queued" | "running" | "awaiting_preview" | "partial" | "done" | "cancelled" | "failed"yes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/runs/string/preview-decision" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"decision": "continue"
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"decision": {
"type": "string",
"enum": [
"continue",
"stop"
]
}
},
"required": [
"decision"
]
}Response 200 Copy
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"mode": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"queued",
"running",
"awaiting_preview",
"partial",
"done",
"cancelled",
"failed"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "number"
},
"total": {
"type": "number"
},
"step": {
"type": "string"
}
},
"required": [
"done",
"total",
"step"
],
"additionalProperties": false
},
"startedAt": {
"type": "string"
},
"etaSeconds": {
"type": [
"number",
"null"
]
},
"candidatesReady": {
"type": "number"
},
"matchedTotal": {
"type": "number"
},
"paidFor": {
"type": "number"
},
"family": {
"type": "string"
},
"previewReady": {
"type": "boolean"
},
"previewDecision": {
"anyOf": [
{
"type": "string",
"enum": [
"pending",
"continue",
"stopped"
]
},
{
"type": "null"
}
]
},
"skippedSources": {
"type": "number"
},
"queuedBehind": {
"anyOf": [
{
"type": "object",
"properties": {
"runId": {
"type": "string"
},
"label": {
"type": "string"
},
"etaAt": {
"type": "string"
}
},
"required": [
"runId",
"label",
"etaAt"
],
"additionalProperties": {}
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"mode",
"state",
"progress",
"startedAt",
"etaSeconds",
"candidatesReady",
"matchedTotal",
"paidFor",
"family",
"previewReady",
"previewDecision",
"skippedSources",
"queuedBehind"
],
"additionalProperties": {},
"description": "One discovery run (the app's Run). The single-run read adds `activity` and, where the mode has one, `graph`, `likers` or `search`; the list adds `searchSummary`, `tokens` and `promotedCount`."
}POST /v1/discovery/runs/{run_id}/promote
Move a run's results into the CRM as leads.
Send candidate_ids (1 to 200) or all: true (the next 200 results not yet moved, not rejected and with a usable Instagram handle, in delivery order; has_more says whether to send it again). Someone the workspace already has becomes a duplicate of that lead, never a second lead. folder_id and tags apply to the leads this request creates, in a step after the move: if that step fails the leads exist unfiled, and moving the same results again creates nothing and files nothing, so file them through the leads operations. Moving the same results twice creates nothing the second time.
Operation id discovery.candidates.promoteScopes discovery:read, leads:writeRate class `discovery_spend` , plus leads_created_dayIdempotency `Idempotency-Key` accepted Keys Developer keys
Name Type Required Description run_idstringyes A run id (uuid). An id that is not a run of this workspace answers 404.. 1 to 64 characters
Field Type Required Description alltrueno candidate_idsuuid[]no 1 to 200 items folder_iduuidno tagsstring[]no 1 to 20 items
Field Type Required Description createdintegeryes -9007199254740991 to 9007199254740991 duplicatesintegeryes -9007199254740991 to 9007199254740991 has_morebooleanyes lead_idsstring[]yes The leads this request created. Empty on an idempotent replay. run_idstringyes
Every operation can also answer the shared errors : authentication, scopes, rate limits and validation.
bash Copy
curl -X POST "https://api.dmhero.ai/v1/discovery/runs/string/promote" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"all": true,
"tags": [
"discovery"
]
}'JSON Schema Request body Copy
{
"type": "object",
"properties": {
"candidate_ids": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"all": {
"type": "boolean",
"const": true
},
"folder_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"tags": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 50
}
}
}
}Response 200 Copy
{
"type": "object",
"properties": {
"run_id": {
"type": "string"
},
"created": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"duplicates": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"lead_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "The leads this request created. Empty on an idempotent replay."
},
"has_more": {
"type": "boolean"
}
},
"required": [
"run_id",
"created",
"duplicates",
"lead_ids",
"has_more"
],
"additionalProperties": false
}