Arc Intelligence API Developer Guide
Introduction
The Arc Intelligence API provides AI-powered content tools for Arc XP customers. This guide will help you integrate the API into your applications, regardless of programming language.
What’s Available
-
Prompt Management - Store and render reusable prompt templates with variable substitution
-
AI Response Generation - Generate text responses from language models with streaming or background processing
-
Vector Search - Find semantically similar stories, images, and videos using natural language queries
-
TypeScript SDK - https://github.com/arcxp/arc-intelligence-typescript-sdk/pkgs/npm/arc-intelligence-typescript-sdk
Base URL Structure
The API endpoint follows this pattern:
https://api.{your-org-id}.arcpublishing.com/intelligence/api
Replace {your-org-id}
with your organization identifier. Different environments use subdomains:
- Production:
https://api.{your-org-id}.arcpublishing.com/intelligence/api
- Sandbox:
https://api.sandbox.{your-org-id}.arcpublishing.com/intelligence/api
Getting Started
Authentication
All API requests require authentication using a Bearer token in the Authorization
header.
curl https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts \ -H "Authorization: Bearer YOUR_API_TOKEN"
You can obtain API tokens from the Arc Developer Center. Read more about the developer center here.
Your First Request
Let’s start with a simple API health check by listing prompts:
curl https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json"
Response:
{ "items": [], "next_token": null}
If you receive this response, you’re connected and authenticated successfully.
Prompt Management
Prompts are reusable templates with variable placeholders. They use Mustache-style syntax for variables like {{variable_name}}
.
Note: The prompt management endpoints are optional convenience features. You can use the AI response generation endpoints directly without storing prompts.
Creating a Prompt
Create a new prompt template:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt_id": "article-summary", "prompt_text": "Summarize this article in 3 sentences: {{article_text}}", "variables": ["article_text"] }'
Response (201 Created):
{ "prompt_id": "article-summary", "prompt_text": "Summarize this article in 3 sentences: {{article_text}}", "variables": ["article_text"], "version": 1, "updated_at": "2024-01-15T10:30:00Z"}
The response includes a version
number that increments with each update.
Retrieving a Prompt
Get an existing prompt by its ID:
curl https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts/article-summary \ -H "Authorization: Bearer YOUR_API_TOKEN"
Response:
{ "prompt_id": "article-summary", "prompt_text": "Summarize this article in 3 sentences: {{article_text}}", "variables": ["article_text"], "version": 1, "updated_at": "2024-01-15T10:30:00Z"}
Updating a Prompt
Updates require the current version
number to prevent conflicts. If someone else updated the prompt since you fetched it, you’ll receive a 409 Conflict error.
curl -X PUT https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts/article-summary \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt_id": "article-summary", "prompt_text": "Write a 3-sentence summary of this article: {{article_text}}", "variables": ["article_text"], "version": 1 }'
Response (200 OK):
{ "prompt_id": "article-summary", "prompt_text": "Write a 3-sentence summary of this article: {{article_text}}", "variables": ["article_text"], "version": 2, "updated_at": "2024-01-15T11:00:00Z"}
The version
incremented from 1 to 2.
Rendering a Prompt
Fill in template variables to get the final text:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts/render \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt_id": "article-summary", "variables": { "article_text": "Scientists at MIT have developed a new solar panel that is 40% more efficient than current models." } }'
Response:
{ "rendered": "Write a 3-sentence summary of this article: Scientists at MIT have developed a new solar panel that is 40% more efficient than current models.", "prompt_id": "article-summary", "version": 2}
Listing Prompts
Retrieve all prompts with pagination support:
curl "https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts?limit=50" \ -H "Authorization: Bearer YOUR_API_TOKEN"
Response:
{ "items": [ { "prompt_id": "article-summary", "prompt_text": "Write a 3-sentence summary of this article: {{article_text}}", "variables": ["article_text"], "version": 2, "updated_at": "2024-01-15T11:00:00Z" } ], "next_token": null}
If next_token
is present, use it to fetch the next page:
curl "https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts?next_token=TOKEN_VALUE" \ -H "Authorization: Bearer YOUR_API_TOKEN"
Deleting a Prompt
Remove a prompt permanently:
curl -X DELETE https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts/article-summary \ -H "Authorization: Bearer YOUR_API_TOKEN"
Response (204 No Content):
No response body is returned for successful deletions.
AI Response Generation
The API can generate text using language models in two modes: background processing with polling, or real-time streaming.
Background Response with Polling
For background processing, create a response and then poll for completion.
Step 1: Create the Response
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/create-response \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "input": "Explain quantum computing in simple terms", "reasoning_effort": "low" }'
Response:
{ "id": "abc123xyz", "status": "queued", "output_text": null}
Step 2: Poll for Completion
Use the id
from the previous response to check the status:
curl https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/retrieve/abc123xyz \ -H "Authorization: Bearer YOUR_API_TOKEN"
Response (while processing):
{ "id": "abc123xyz", "status": "in_progress", "output_text": null}
Response (when complete):
{ "id": "abc123xyz", "status": "completed", "output_text": "Quantum computing uses quantum mechanics principles to process information. Unlike traditional computers that use bits (0 or 1), quantum computers use quantum bits or qubits that can be both 0 and 1 simultaneously. This allows them to solve certain complex problems much faster than conventional computers."}
Keep polling until status
is either completed
or failed
. Wait about 1 second between poll requests.
Streaming Responses
For real-time output, use Server-Sent Events (SSE) by setting the Accept
header to text/event-stream
.
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/create-response \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{ "input": "Write a short story about a robot learning to paint" }'
Response (Server-Sent Events):
event: message_startdata: {"type": "message_start"}
event: output_text.deltadata: {"type": "output_text.delta", "delta": "The robot's"}
event: output_text.deltadata: {"type": "output_text.delta", "delta": " fingers were"}
event: output_text.deltadata: {"type": "output_text.delta", "delta": " designed for precision"}
...
event: message_stopdata: {"type": "message_stop"}
The stream starts with message_start
, followed by multiple output_text.delta
events containing text chunks, and ends with message_stop
.
Structured Output with JSON Schema
Constrain responses to match a specific JSON structure:
Note: When using structured output with a JSON schema, you must explicitly disable unexpected fields.
Set"additionalProperties": false
on the top-level schema object — and any nested objects if needed — to ensure the model only returns the fields defined in your schema.
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/create-response \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "input": "Analyze this article and extract structured metadata: Scientists at MIT have developed a new type of solar panel that is 40% more efficient than current models.", "reasoning_effort": "minimal", "json_schema": { "type": "object", "additionalProperties": false, "properties": { "title": { "type": "string", "description": "A catchy headline under 80 characters" }, "summary": { "type": "string", "description": "A 2-3 sentence summary of the main points" }, "tags": { "type": "array", "items": {"type": "string"}, "description": "Relevant topic tags" }, "sentiment": { "type": "string", "enum": ["positive", "neutral", "negative"], "description": "Overall sentiment of the content" } }, "required": ["title", "summary", "tags", "sentiment"] } }'
Poll for the result as shown in the background response section. The output_text
will be valid JSON matching your schema:
{ "id": "xyz789", "status": "completed", "output_text": "{\"title\": \"MIT Scientists Create Solar Panel 40% More Efficient\", \"summary\": \"Researchers at MIT have developed a new solar panel that is 40% more efficient than current models. This breakthrough could significantly reduce renewable energy costs.\", \"tags\": [\"solar power\", \"renewable energy\", \"materials science\"], \"sentiment\": \"positive\"}"}
When including a JSON schema, provide clear descriptions for each property so the model understands what you want.
Reasoning Effort Levels
The reasoning_effort
parameter controls the tradeoff between speed and quality:
minimal
- Fastest, good for simple taskslow
- Quick responses for straightforward requestsmedium
- Balanced speed and quality (default)high
- Slower but more thorough for complex analysis
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/create-response \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "input": "What is 2+2?", "reasoning_effort": "minimal" }'
Use minimal
or low
for simple queries, and high
for complex reasoning tasks.
Multi-Turn Conversations
Provide conversation history as an array of messages:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/responses/create-response \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "input": [ {"role": "user", "content": "What is the capital of France?"}, {"role": "assistant", "content": "The capital of France is Paris."}, {"role": "user", "content": "What is its population?"} ], "reasoning_effort": "low" }'
The AI maintains context from previous messages and understands that “its” refers to Paris.
Vector Search
Find semantically similar content across your stories, images, and videos using natural language queries.
Searching Stories
Search story content using a semantic query:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/vector/search/stories \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "climate change legislation", "limit": 10 }'
Response:
{ "results": [ { "id": "story-123", "score": 0.85, "text": "Congress passed landmark climate change legislation today that aims to reduce carbon emissions by 50% over the next decade...", "metadata": { "headline": "Congress Passes Historic Climate Bill", "publish_date": "2024-01-15T09:00:00Z", "websites": [ { "name": "news-site-id", "sections": ["/politics", "/environment"] } ] } } ]}
The score
represents relevance (higher is more relevant). Results are ordered by score in descending order.
Filtering Stories by Website and Section
Narrow down results using metadata filters:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/vector/search/stories \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "election coverage", "limit": 5, "metadata_filter": { "websites": { "my-news-site-id": { "sections": ["/politics", "/elections"] }, "my-blog-id": { "sections": ["/opinion/politics"] } }, "publish_date_after": "2024-01-01T00:00:00Z", "publish_date_before": "2024-12-31T23:59:59Z", "excluded_content_ids": ["story-456", "story-789"] } }'
Metadata filters include:
websites
- Map of website IDs to section filterspublish_date_after
- Include stories published on or after this timestamppublish_date_before
- Include stories published on or before this timestampexcluded_content_ids
- Array of content IDs to exclude from results
Searching Images
Search image content with optional metadata filters:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/vector/search/images \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "sunset over mountains", "limit": 20, "metadata_filter": { "licensable": true, "sponsored": false, "created_date_after": "2023-01-01T00:00:00Z" } }'
Response:
{ "results": [ { "id": "image-123", "score": 0.92, "text": "Vibrant orange and pink sunset over snow-capped mountain peaks", "metadata": { "subtitle": "Sunset view from Rocky Mountain National Park", "licensable": true, "sponsored": false, "published": true, "created_date": "2023-06-15T14:30:00Z" } } ]}
Image metadata filters include:
licensable
- Filter by whether the image can be licensedsponsored
- Filter by sponsored content statuspublished
- Filter by publication statuscreated_date_after
- Include images created on or after this timestampcreated_date_before
- Include images created on or before this timestampexcluded_content_ids
- Array of content IDs to exclude
Searching Videos
Search video content with category and website filters:
curl -X POST https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/vector/search/videos \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "breaking news coverage", "limit": 10, "metadata_filter": { "category": "news", "websites": { "video-site-id": { "sections": ["/news/breaking"] } }, "published_after": "2024-01-01T00:00:00Z", "published_before": "2024-12-31T23:59:59Z", "last_published_after": "2024-06-01T00:00:00Z" } }'
Response:
{ "results": [ { "id": "video-123", "score": 0.88, "metadata": { "category": "news", "websites": [ { "name": "video-site-id", "sections": ["/news/breaking"] } ], "last_updated_date": "2024-01-15T08:00:00Z" } } ]}
Video metadata filters include:
category
- Filter by video categorywebsites
- Map of website IDs to section filterspublished_after
- Include videos published on or after this timestamppublished_before
- Include videos published on or before this timestamplast_published_after
- Include videos last published on or after this timestamplast_published_before
- Include videos last published on or before this timestamp
Error Handling
The API uses standard HTTP status codes to indicate success or failure.
Common Status Codes
- 200 OK - Request succeeded
- 201 Created - Resource created successfully
- 204 No Content - Request succeeded with no response body (typically for DELETE)
- 400 Bad Request - Invalid input (missing required fields, wrong format)
- 404 Not Found - Resource doesn’t exist
- 409 Conflict - Version mismatch when updating a prompt
- 422 Unprocessable Entity - Request body failed validation
Error Response Structure
Error responses follow this structure:
{ "detail": "Human-readable error message describing what went wrong"}
Handling Version Conflicts
When updating a prompt, if the version has changed since you fetched it, you’ll receive a 409 Conflict:
Request:
curl -X PUT https://api.{your-org-id}.arcpublishing.com/intelligence/api/v1/prompts/article-summary \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "prompt_id": "article-summary", "prompt_text": "Updated text", "variables": ["article_text"], "version": 1 }'
Response (409 Conflict):
{ "detail": "Version conflict: expected version 2, got 1. Fetch the latest version and try again."}
To resolve this, fetch the latest version first and then retry the update with the current version number.
Validation Errors
When request validation fails, you’ll receive a 422 status with details:
Response (422 Unprocessable Entity):
{ "detail": "Validation failed: missing required field 'prompt_text'"}
API Reference Summary
Prompt Management Endpoints
Method | Path | Description |
---|---|---|
POST | /v1/prompts | Create a new prompt |
GET | /v1/prompts | List all prompts with pagination |
GET | /v1/prompts/{prompt_id} | Get a specific prompt |
PUT | /v1/prompts/{prompt_id} | Update an existing prompt |
DELETE | /v1/prompts/{prompt_id} | Delete a prompt |
POST | /v1/prompts/render | Render a prompt with variables |
Response Generation Endpoints
Method | Path | Description |
---|---|---|
POST | /v1/responses/create-response | Create a model response (background or streaming) |
GET | /v1/responses/retrieve/{response_id} | Get response status and output |
Vector Search Endpoints
Method | Path | Description |
---|---|---|
POST | /v1/vector/search/stories | Search story content |
POST | /v1/vector/search/images | Search image content |
POST | /v1/vector/search/videos | Search video content |
Usage Endpoints
Method | Path | Description |
---|---|---|
GET | /v1/usage/monthly?month=YYYY-MM | Get monthly usage statistics |
Additional Resources
- Developer Center: Read more about the developer center here for API token management and additional documentation
- Community Hub: Join the ArcXP Community at https://dev.arcxp.com/community/ for support and discussions