Actions & Generated Content¶
Completed visibility reports can recommend actions. The workspace action collection is the canonical place to read those recommendations, including actions that have been recommended again by later reports.
Actions with executable: true can generate articles, LinkedIn posts, X posts, or Reddit posts. Generation is asynchronous.
flowchart TB
A[List workspace actions] --> B[Choose an executable action]
B --> C[Launch action execution]
C --> D{Poll execution status}
D -->|queued / running| D
D -->|failed| E[Read execution error]
D -->|succeeded| F[Retrieve generated output]
F --> G{Article has images?}
G -->|No| H[Use generated content]
G -->|Yes| I[Fetch signed image URL]
I --> H
Action types and statuses¶
type | Executable | Purpose |
|---|---|---|
create_article | Yes | Generate an article |
create_linkedin_post | Yes | Generate a LinkedIn post |
create_x_post | Yes | Generate an X post or thread |
create_reddit_post | Yes | Generate a Reddit post |
technical_change | No | Describe a technical website change |
check_llms_txt | No | Describe an llms.txt finding and recommendation |
check_robots_txt | No | Describe a robots.txt finding and recommendation |
request_third_party_mention | No | Recommend outreach for a third-party mention |
Action status values are recommended, generating, needs_review, completed, dismissed, snoozed, failed, and superseded.
Only actions in recommended, failed, or snoozed status can start an execution. A successful generation moves the action to needs_review; the current API has no action-status update endpoint.
List workspace actions¶
Required scope: actions:read
Query parameters¶
| Parameter | Type | Default | Rules |
|---|---|---|---|
limit | integer | 50 | Minimum 1, maximum 100 |
cursor | string or null | null | Exact pagination.next_cursor from the preceding page |
status | enum or null | null | Any action status listed above |
created_after | RFC 3339 date-time or null | null | Strict lower bound; timezone required |
created_before | RFC 3339 date-time or null | null | Strict upper bound; timezone required |
Filters are combined with AND. When both timestamps are supplied, created_after must be earlier than created_before. Results are ordered newest first by created_at.
Example request:
curl --get \
--url "$NBLICK_API_BASE_URL/v1/workspaces/pws-V1StGXR8_Z5jdHi6B-myT/actions" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
--data-urlencode "status=recommended" \
--data-urlencode "limit=50"
Response — 200 OK:
{
"data": [
{
"id": "act-fG8kdE3yP0aX7sL2mN9qR",
"workspace_id": "pws-V1StGXR8_Z5jdHi6B-myT",
"report_id": "pvr-8xR2kQpL_5jdHi6B-myT",
"type": "create_article",
"status": "recommended",
"priority": "high",
"executable": true,
"target_engines": ["gemini"],
"title": "Publish a remote hiring comparison guide",
"description": "Create a practical comparison page for remote hiring buyers.",
"why_it_matters": "The brand is absent from high-intent comparison answers.",
"expected_impact": "Improve future mentions and citation share.",
"evidence": {},
"payload": {
"article_title": "How to choose a remote hiring platform",
"category": "comparison",
"language": "en",
"word_range": "1500-2000",
"additional_information": null,
"prompt_ids": ["report:prompt:0"],
"generate_images": true,
"image_count": 2,
"include_faq": true,
"resource_urls": []
},
"first_recommended_at": "2026-08-31T12:07:00Z",
"last_recommended_at": "2026-08-31T12:07:00Z",
"created_at": "2026-08-31T12:07:00Z",
"updated_at": null
}
],
"pagination": {
"next_cursor": null,
"has_more": false
}
}
| Status | When |
|---|---|
200 | Page returned |
400 | Cursor is invalid for this workspace or the active filters |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:read |
404 | Workspace does not exist or belongs to another partner |
422 | Limit, status, timestamp, header, or date range is invalid |
Retrieve one action¶
Required scope: actions:read
| Path parameter | Type | Description |
|---|---|---|
action_id | string | Globally unique action ID returned by a report or action collection |
Example request:
curl \
--url "$NBLICK_API_BASE_URL/v1/actions/act-fG8kdE3yP0aX7sL2mN9qR" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Response — 200 OK before the first execution:
{
"action": {
"id": "act-fG8kdE3yP0aX7sL2mN9qR",
"workspace_id": "pws-V1StGXR8_Z5jdHi6B-myT",
"report_id": "pvr-8xR2kQpL_5jdHi6B-myT",
"type": "create_article",
"status": "recommended",
"priority": "high",
"executable": true,
"target_engines": ["gemini"],
"title": "Publish a remote hiring comparison guide",
"description": "Create a practical comparison page for remote hiring buyers.",
"why_it_matters": "The brand is absent from high-intent comparison answers.",
"expected_impact": "Improve future mentions and citation share.",
"evidence": {},
"payload": {
"article_title": "How to choose a remote hiring platform",
"category": "comparison",
"language": "en",
"word_range": "1500-2000",
"additional_information": null,
"prompt_ids": ["report:prompt:0"],
"generate_images": true,
"image_count": 2,
"include_faq": true,
"resource_urls": []
},
"first_recommended_at": "2026-08-31T12:07:00Z",
"last_recommended_at": "2026-08-31T12:07:00Z",
"created_at": "2026-08-31T12:07:00Z",
"updated_at": null
},
"latest_execution": null
}
After executions exist, latest_execution contains the highest attempt number in the execution response shape documented below.
| Status | When |
|---|---|
200 | Action and latest execution returned |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:read |
404 | Action does not exist or belongs to another partner |
422 | Header validation fails |
Action response fields¶
| Field | Type | Description |
|---|---|---|
id | string | Opaque action identifier |
workspace_id | string | Owning workspace |
report_id | string | Report that most recently recommended the action |
type | enum | Action type |
status | enum | Action lifecycle status |
priority | enum | high, medium, or low |
executable | boolean | Whether the API can generate output for this action |
target_engines | array of strings | Answer engines targeted by the recommendation |
title | string | Short recommendation title |
description | string | Work to perform |
why_it_matters | string | Rationale |
expected_impact | string | Expected result |
evidence | object | Evidence supporting the recommendation |
payload | object | Type-specific execution or implementation data |
first_recommended_at | date-time | First recommendation timestamp |
last_recommended_at | date-time | Most recent recommendation timestamp |
created_at | date-time | Action creation timestamp |
updated_at | date-time or null | Last action update |
Executable payloads have these fields:
| Action type | Payload |
|---|---|
create_article | Required: article_title, category, language. Also: word_range, additional_information, prompt_ids, generate_images, image_count (1–4), include_faq, resource_urls (maximum 5) |
create_linkedin_post | Required: topic, language. Also: additional_information, prompt_ids, generate_image, post_type |
create_x_post | Required: topic, language. Also: additional_information, prompt_ids, generate_image |
create_reddit_post | Required: topic, language. Also: additional_information, prompt_ids |
Manual-action payloads use:
| Action type | Payload |
|---|---|
technical_change | target_url, non-empty issues, non-empty implementation_steps, non-empty acceptance_criteria |
check_llms_txt, check_robots_txt | url, present, status_code, blocked_agents, recommendation |
request_third_party_mention | 1–10 target_urls, outreach_angle, suggested_request, and prompt_ids |
Launch an action execution¶
POST /v1/actions/{action_id}/executions
Authorization: Bearer <partner-api-key>
Content-Type: application/json
Required scope: actions:write
The request body is optional. With no body, the execution uses the action's payload. To change supported fields for this attempt, send a partial payload_override; it is merged over the action payload before validation.
Example article request:
curl --request POST \
--url "$NBLICK_API_BASE_URL/v1/actions/act-fG8kdE3yP0aX7sL2mN9qR/executions" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"payload_override": {
"article_title": "A practical guide to choosing a remote hiring platform",
"generate_images": true,
"image_count": 2,
"resource_urls": ["https://customer.example/remote-hiring"]
}
}'
Supported overrides¶
| Article override | Type | Rules |
|---|---|---|
category | string or null | Replaces the action category |
article_title | string or null | Replaces the title |
language | string or null | Replaces the language |
word_range | string or null | Replaces the target word range |
additional_information | string or null | Additional instructions |
prompt_ids | array of strings or null | Replaces prompt references |
generate_images | boolean or null | Whether article generation includes images |
image_count | integer or null | 1–4 |
include_faq | boolean or null | Whether to include an FAQ |
resource_urls | array of strings or null | Maximum 5 |
| Social override | Type | Applies to |
|---|---|---|
topic | string or null | LinkedIn, X, Reddit |
language | string or null | LinkedIn, X, Reddit |
additional_information | string or null | LinkedIn, X, Reddit |
prompt_ids | array of strings or null | LinkedIn, X, Reddit |
generate_image | boolean or null | LinkedIn and X |
post_type | enum or null | LinkedIn only |
For LinkedIn, post_type defaults to text_only. Current generation supports text_only, single_image, multi_image, article, celebrate_occasion, and poll. The schema also recognizes video, newsletter, document, and repost, but generation for those values returns 503 action_output_not_queued.
Send only fields you intend to override. Unknown top-level or override fields return 422.
Response — 202 Accepted:
{
"id": "aex-P6vB2nQ8rD4kW1yH7cM5t",
"action_id": "act-fG8kdE3yP0aX7sL2mN9qR",
"status": "running",
"attempt": 1,
"output_type": "article",
"output_id": "art-K9sD3fL6qT1vN8wC4xR2p",
"output_url": null,
"error": null,
"created_at": "2026-08-31T12:10:00Z",
"started_at": "2026-08-31T12:10:01Z",
"completed_at": null,
"updated_at": "2026-08-31T12:10:01Z"
}
A successful launch normally returns running with output_type and output_id populated. The polling resource can still represent queued with those fields set to null before output creation starts. Article output_url remains null until the execution succeeds.
| Status | When |
|---|---|
202 | Execution accepted |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:write |
404 | Action does not exist or belongs to another partner |
409 | Action is manual or cannot execute in its current status |
422 | Request body or merged action payload is invalid |
503 | Output was not queued; response code is action_output_not_queued |
Action executions do not accept an idempotency key. A 503 leaves the action in failed, from which a new attempt can be launched.
Poll an action execution¶
Required scope: actions:read
Example request:
curl \
--url "$NBLICK_API_BASE_URL/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Response — 200 OK after success:
{
"id": "aex-P6vB2nQ8rD4kW1yH7cM5t",
"action_id": "act-fG8kdE3yP0aX7sL2mN9qR",
"status": "succeeded",
"attempt": 1,
"output_type": "article",
"output_id": "art-K9sD3fL6qT1vN8wC4xR2p",
"output_url": "/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output",
"error": null,
"created_at": "2026-08-31T12:10:00Z",
"started_at": "2026-08-31T12:10:01Z",
"completed_at": "2026-08-31T12:13:00Z",
"updated_at": "2026-08-31T12:13:00Z"
}
| Execution status | Terminal | Meaning |
|---|---|---|
queued | No | Accepted but not started |
running | No | Content generation is active |
succeeded | Yes | Final output is ready |
failed | Yes | Generation ended unsuccessfully; error is populated |
attempt starts at 1 and increases for each new execution of the same action. output_type is article, linkedin_post, x_post, reddit_post, or null. output_url is relative to the API base URL.
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string | No | Opaque execution identifier |
action_id | string | No | Executed action |
status | enum | No | Execution lifecycle status |
attempt | integer | No | One-based attempt number for the action |
output_type | enum | Yes | Generated resource type once output creation starts |
output_id | string | Yes | Generated resource ID once output creation starts |
output_url | string | Yes | Relative generated-output URL when available |
error | string | Yes | Failure detail when status is failed |
created_at | date-time | No | Execution creation time |
started_at | date-time | Yes | Generation start time |
completed_at | date-time | Yes | Terminal completion time |
updated_at | date-time | Yes | Last execution update |
| Status | When |
|---|---|
200 | Execution returned |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:read |
404 | Execution does not exist or belongs to another partner |
422 | Header validation fails |
Retrieve generated output¶
Required scope: actions:read
Wait for status: "succeeded" before retrieving the final output. Article output always returns 409 output_not_ready before success. A social output resource can become readable while the execution is still running, but its content fields may still be null; polling the execution to succeeded is the reliable final-content workflow.
Example request:
curl \
--url "$NBLICK_API_BASE_URL/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Response — 200 OK for an article:
{
"output_type": "article",
"output": {
"id": "art-K9sD3fL6qT1vN8wC4xR2p",
"status": "completed",
"article_title": "A practical guide to choosing a remote hiring platform",
"language": "en",
"category": "comparison",
"meta_title": "How to choose a remote hiring platform",
"meta_description": "Compare the capabilities that matter when hiring remote professionals.",
"slug": "choose-remote-hiring-platform",
"content": "# How to choose a remote hiring platform\n\nStart with the roles, skills, and engagement model your team needs...",
"images": [
{
"url": "https://partner.api.nblick.com/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output/images/0?expires=1788179400&signature=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"mime_type": "image/webp",
"alt_text": "A distributed team reviewing remote candidates",
"caption": "Evaluate remote hiring platforms against your workflow.",
"section_hint": "after_intro",
"width": 1200,
"height": 630,
"is_placeholder": false
}
],
"article_plan": {
"sections": [
{"heading": "Define your hiring needs"},
{"heading": "Compare platform capabilities"}
]
},
"sources": [
{
"title": "Remote hiring",
"url": "https://customer.example/remote-hiring"
}
],
"created_at": "2026-08-31T12:10:01Z",
"updated_at": "2026-08-31T12:13:00Z"
}
}
Article fields meta_title, meta_description, slug, content, images, article_plan, sources, and updated_at are nullable.
| Article field | Type | Nullable |
|---|---|---|
id | string | No |
status | generating, completed, or failed | No |
article_title | string | No |
language | string | No |
category | string | No |
meta_title | string | Yes |
meta_description | string | Yes |
slug | string | Yes |
content | string | Yes |
images | array of article image objects | Yes |
article_plan | object | Yes |
sources | array of {title, url} | Yes |
created_at | date-time | No |
updated_at | date-time | Yes |
Each article image object contains:
| Field | Type | Nullable |
|---|---|---|
url | string | No |
mime_type | string | No |
alt_text | string | No |
caption | string | Yes |
section_hint | string | Yes |
width | integer | Yes |
height | integer | Yes |
is_placeholder | boolean | No |
Response — 200 OK for a LinkedIn post:
{
"output_type": "linkedin_post",
"output": {
"id": "lnk-W4mQ8dR2yT6pL1sN9cV3x",
"status": "completed",
"platform": "linkedin",
"topic": "What to compare in a remote hiring platform",
"language": "en",
"content": "Hiring remotely works best when the platform matches your workflow...",
"tweets": null,
"subreddit": null,
"title": null,
"body": null,
"post_plan": {
"hook": "Remote hiring is not one-size-fits-all."
},
"images": [
{
"image_bytes_b64": "UklGRiQAAABXRUJQVlA4...",
"alt_text": "Remote hiring workflow",
"caption": null,
"is_placeholder": false
}
],
"created_at": "2026-08-31T12:10:01Z",
"updated_at": "2026-08-31T12:12:00Z"
}
}
Social output fields vary by platform:
| Platform | Main content fields | Image behavior |
|---|---|---|
linkedin | content | images may contain base64-encoded image bytes |
x | tweets | images is null in this response shape |
reddit | subreddit, title, body | images is null |
All social outputs also include id, status (generating, completed, or failed), platform, topic, language, nullable post_plan, created_at, and nullable updated_at. Fields for the other platforms are returned as null.
| Social output field | Type | Nullable |
|---|---|---|
id | string | No |
status | generating, completed, or failed | No |
platform | linkedin, x, or reddit | No |
topic | string | No |
language | string | No |
content | string | Yes |
tweets | array of strings | Yes |
subreddit | string | Yes |
title | string | Yes |
body | string | Yes |
post_plan | object | Yes |
images | array of social image objects | Yes |
created_at | date-time | No |
updated_at | date-time | Yes |
A social image object contains base64 image_bytes_b64, alt_text, nullable caption, and is_placeholder.
| Status | When |
|---|---|
200 | Output returned |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:read |
404 | Execution or generated output does not exist or belongs to another partner |
409 | Output resource is not ready; response code is output_not_ready |
422 | Header validation fails |
Generate or replace an article image¶
POST /v1/action-executions/{execution_id}/output/images/{image_index}/generate
Authorization: Bearer <partner-api-key>
Content-Type: application/json
Required scope: actions:write
This synchronous endpoint replaces an existing image slot in a successfully generated article.
| Path parameter | Type | Rules |
|---|---|---|
execution_id | string | Successful article execution |
image_index | integer | Zero-based existing image position; minimum 0 |
Request body¶
| Field | Type | Required | Rules |
|---|---|---|---|
generation_type | enum | Yes | ai_generated, user_provided, or ai_inspired |
user_image_b64 | string or null | For user_provided and ai_inspired | Base64-encoded image bytes |
user_image_mime_type | string | No | Defaults to image/jpeg; use image/jpeg, image/png, or image/webp |
user_prompt | string or null | No | Optional instruction for AI generation |
use_article_context | boolean | No | Defaults to true |
Example request:
curl --request POST \
--url "$NBLICK_API_BASE_URL/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output/images/0/generate" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"generation_type": "ai_generated",
"user_prompt": "Show a diverse remote team comparing hiring options",
"use_article_context": true
}'
Response — 200 OK:
{
"url": "https://partner.api.nblick.com/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output/images/0?expires=1788179700&signature=fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
"mime_type": "image/webp",
"alt_text": "A diverse remote team comparing hiring options",
"caption": "Choose a platform that fits the way your team hires.",
"section_hint": "after_intro",
"width": 1200,
"height": 630,
"is_placeholder": false
}
Replacing an image invalidates the previous signed URL for that position. Use the URL returned by this response or retrieve the article output again.
| Status | When |
|---|---|
200 | Image generated or replaced |
400 | Image index, base64 data, or uploaded image is invalid |
401 | Partner credential is missing or invalid |
403 | Credential lacks actions:write |
404 | Execution, article, output, or image slot is unavailable to the authenticated partner |
409 | Execution is not a successful article output; code is article_output_required or output_not_ready |
422 | Request body, enum, path, or header validation fails |
500 | Image generation or replacement fails |
Retrieve an article image¶
GET /v1/action-executions/{execution_id}/output/images/{image_index}?expires={expires}&signature={signature}
Authentication: the exact signed URL returned in an article image object. No bearer API key or API scope is required.
| Parameter | Location | Type | Required | Rules |
|---|---|---|---|---|
execution_id | Path | string | Yes | Execution encoded in the returned image URL |
image_index | Path | integer | Yes | Zero-based image position; minimum 0 |
expires | Query | integer | Yes | Expiration encoded in the returned image URL; minimum 0 |
signature | Query | string | Yes | Signature encoded in the returned image URL; exactly 64 characters |
Do not construct expires or signature yourself. Follow the complete url returned by the output or image-generation endpoint.
Example request:
curl \
--output "remote-hiring.webp" \
"https://partner.api.nblick.com/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output/images/0?expires=1788179700&signature=fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
Response — 200 OK:
Possible success media types are image/png, image/jpeg, image/webp, and image/gif.
| Status | When |
|---|---|
200 | Image bytes returned |
404 | URL is invalid, expired, belongs to another host, refers to a replaced image, or the image no longer exists |
422 | Path or signed-query parameter format is invalid |