Quickstart¶
This walkthrough goes from a customer website to a completed visibility report and generated article.
Before you begin¶
You need:
- the partner-specific API hostname supplied by nBlick;
- a partner API key with
workspaces:write,reports:write,reports:read,actions:write, andactions:read.
Add workspaces:read if the integration also lists or retrieves workspaces.
export NBLICK_API_BASE_URL="https://<partner-slug>.api.nblick.com"
export NBLICK_PARTNER_API_KEY="nbp_..."
Keep the API key in the partner backend. Do not expose it to browser or mobile clients.
1. Create or reuse a workspace¶
curl --request POST \
--url "$NBLICK_API_BASE_URL/v1/workspaces" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
--header "Content-Type: application/json" \
--header "X-External-Actor-Id: operator-42" \
--data '{
"website": "https://customer.example",
"models": [
{"id": "openai", "enabled": true},
{"id": "gemini", "enabled": true},
{"id": "claude", "enabled": false}
]
}'
Response — 201 Created:
{
"id": "pws-V1StGXR8_Z5jdHi6B-myT",
"website": "https://customer.example/",
"status": "active",
"models": [
{"id": "openai", "enabled": true},
{"id": "gemini", "enabled": true},
{"id": "claude", "enabled": false}
],
"created_at": "2026-08-31T12:00:00Z",
"updated_at": null
}
Save the workspace ID. Repeating the canonical website returns the same workspace and preserves its original model selection.
2. Launch a visibility report¶
The request has no JSON body.
curl --request POST \
--url "$NBLICK_API_BASE_URL/v1/workspaces/$WORKSPACE_ID/visibility-reports" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY" \
--header "Idempotency-Key: customer-visibility-2026-08-31"
Response — 202 Accepted:
{
"id": "pvr-8xR2kQpL_5jdHi6B-myT",
"workspace_id": "pws-V1StGXR8_Z5jdHi6B-myT",
"status": "queued",
"result": null,
"error": null,
"created_at": "2026-08-31T12:01:00Z",
"updated_at": null,
"completed_at": null
}
Reuse the same Idempotency-Key only when retrying this logical run. Once a report exists, the key always returns that report, including if it later fails.
3. Poll the report¶
curl \
--url "$NBLICK_API_BASE_URL/v1/visibility-reports/$REPORT_ID" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Continue while status is queued or running. Stop when it is completed or failed.
Response — 200 OK after completion:
{
"id": "pvr-8xR2kQpL_5jdHi6B-myT",
"workspace_id": "pws-V1StGXR8_Z5jdHi6B-myT",
"status": "completed",
"result": {
"report": {
"brand_name": "Customer",
"url": "https://customer.example/",
"category": "Remote hiring",
"description": "A platform that helps companies hire remote professionals.",
"visibility_score": 0.5,
"ai_visibility_score": 50,
"score_band": "good",
"scoring_version": 2,
"score_breakdown": {
"mention_rate": {"value": 0.5, "weight": 0.4, "points": 20.0},
"platform_coverage": {"value": 0.5, "weight": 0.2, "points": 10.0},
"avg_rank": {"value": 0.5, "weight": 0.2, "points": 10.0},
"sentiment": {"value": 0.5, "weight": 0.1, "points": 5.0},
"competitive_gap": {"value": 0.5, "weight": 0.1, "points": 5.0}
},
"answers_analyzed": 2,
"overall": {
"visibility_pct": 0.5,
"mean_reciprocal_rank": 0.5,
"citation_share": 1.0,
"sentiment_counts": {"positive": 1, "neutral": 0, "negative": 0},
"mention_count": 1,
"answers_analyzed": 2,
"branded_answers": 0
},
"per_engine": {
"openai": {
"visibility_pct": 1.0,
"mean_reciprocal_rank": 1.0,
"citation_share": 1.0,
"sentiment_counts": {"positive": 1, "neutral": 0, "negative": 0},
"mention_count": 1,
"answers_analyzed": 1,
"branded_answers": 0
},
"gemini": {
"visibility_pct": 0.0,
"mean_reciprocal_rank": 0.0,
"citation_share": null,
"sentiment_counts": {"positive": 0, "neutral": 0, "negative": 0},
"mention_count": 0,
"answers_analyzed": 1,
"branded_answers": 0
}
},
"competitors": [
{
"name": "Competitor A",
"category": "Remote hiring platform",
"mention_count": 2,
"visibility_pct": 1.0,
"share_of_voice": 0.67,
"mean_reciprocal_rank": 0.75
},
{
"name": "Customer",
"category": "Remote hiring platform",
"mention_count": 1,
"visibility_pct": 0.5,
"share_of_voice": 0.33,
"mean_reciprocal_rank": 0.5
}
],
"prompts": [
{
"text": "What is the best platform for hiring remote professionals?",
"category": "recommendation",
"responses": [
{
"engine": "openai",
"model_id": "gpt-5-mini",
"answer_text": "Customer and Competitor A are two options for hiring remote professionals.",
"citations": [
{
"url": "https://customer.example/remote-hiring",
"title": "Remote hiring",
"snippet": "Find remote professionals for your next project."
}
]
},
{
"engine": "gemini",
"model_id": "gemini-2.5-flash",
"answer_text": "Competitor A is a widely used option for remote hiring.",
"citations": []
}
]
}
],
"root_files": []
},
"proposed_articles": [
{
"prompt_text": "best remote hiring platform",
"category": "comparison",
"impact": "high",
"impact_score": 0.82,
"competitors": ["Competitor A"],
"engines_missing": 1,
"engines_total": 2,
"source": "observed"
}
],
"action_list": [
{
"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
}
]
},
"error": null,
"created_at": "2026-08-31T12:01:00Z",
"updated_at": "2026-08-31T12:07:00Z",
"completed_at": "2026-08-31T12:07:00Z"
}
Save the action ID for an action whose executable field is true.
4. Launch content generation¶
Executing without a body uses the action payload exactly. This example changes the title and adds one reference URL for this attempt.
curl --request POST \
--url "$NBLICK_API_BASE_URL/v1/actions/$ACTION_ID/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",
"resource_urls": ["https://customer.example/remote-hiring"]
}
}'
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. The execution lifecycle also includes queued before generation starts.
5. Poll the action execution¶
curl \
--url "$NBLICK_API_BASE_URL/v1/action-executions/$EXECUTION_ID" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Continue while status is queued or running. Stop when it is succeeded or failed.
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"
}
6. Retrieve the generated article¶
curl \
--url "$NBLICK_API_BASE_URL/v1/action-executions/$EXECUTION_ID/output" \
--header "Authorization: Bearer $NBLICK_PARTNER_API_KEY"
Response — 200 OK:
{
"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": null,
"sources": [
{
"title": "Remote hiring",
"url": "https://customer.example/remote-hiring"
}
],
"created_at": "2026-08-31T12:10:01Z",
"updated_at": "2026-08-31T12:13:00Z"
}
}
7. Download article images¶
Use each images[].url exactly as returned. It is short-lived and already signed, so do not add the bearer API key.
curl \
--output "remote-hiring.webp" \
"https://partner.api.nblick.com/v1/action-executions/aex-P6vB2nQ8rD4kW1yH7cM5t/output/images/0?expires=1788179400&signature=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
If the URL has expired, retrieve the generated output again for a fresh URL. To regenerate or replace an existing article image, follow Generate or replace an article image.
Next steps¶
- Review all workspace fields and filters in Workspaces.
- Read the complete report schema in Visibility Reports.
- Learn the article, social-post, and image variants in Actions & Generated Content.
- Implement status-aware error handling using Permissions & Errors.