Skip to content

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

GET /v1/workspaces/{workspace_id}/actions
Authorization: Bearer <partner-api-key>

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

GET /v1/actions/{action_id}
Authorization: Bearer <partner-api-key>

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.

{
  "detail": {
    "code": "action_output_not_queued"
  }
}

Poll an action execution

GET /v1/action-executions/{execution_id}
Authorization: Bearer <partner-api-key>

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

GET /v1/action-executions/{execution_id}/output
Authorization: Bearer <partner-api-key>

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
{
  "detail": {
    "code": "output_not_ready"
  }
}

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:

HTTP/1.1 200 OK
Content-Type: image/webp
Cache-Control: private, max-age=...

<binary image bytes>

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