← Back to Part 1 — Part 2 of 2
🧩 Press Release Endpoints (cont'd 9/11)
📦 8. Check Press Release Worthiness
Validate if content is worthy of being a press release using AI assessment.
Endpoint: POST /api/cg/v1/press-release/check-worthiness/
Request Body:
headline (string, max 80 chars): Main headline
blog\_headline (string): Alternative blog-style headline
summary (string): Brief summary (15-35 words)
blog\_summary (string): Alternative blog-style summary
content (string): Full press release content (1500-2000 words recommended)
cURL Example:
curl -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/check-worthiness/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"headline": "Company XYZ Launches Revolutionary AI Platform",
"blog_headline": "How Company XYZ is Transforming AI Analytics",
"summary": "Company XYZ today announced the launch of its groundbreaking AI-powered analytics platform, designed to help businesses make data-driven decisions in real-time.",
"blog_summary": "Discover how Company XYZ new AI platform is changing the game for businesses seeking real-time analytics and insights.",
"content": "FOR IMMEDIATE RELEASE\n\nCompany XYZ Unveils Revolutionary AI-Powered Analytics Platform\n\n[CITY, STATE] – January 28, 2025 – Company XYZ, a leader in business intelligence solutions, today announced the launch of..."
}'
Success Response (202 Accepted):
{
"task_id": "c3d4e5f6-a7b8-9012-cdef-123456789012"
}
Task Result (After Polling):
{
"is_valid": true,
"score": 0.85,
"confidence": 0.92,
"reasoning": "This press release announces a significant product launch with clear business value. It includes specific features, target audience, and demonstrates innovation in the AI analytics space. The content is well-structured and newsworthy.",
"suggestions": [
"Include specific metrics or statistics to strengthen credibility",
"Add a quote from a customer or industry analyst",
"Mention partnerships or integrations with known platforms"
]
}
🧩 Press Release Endpoints (cont'd 10/11)
🔧 9. Export Press Release Links
Export media links from press release distribution channels to an Excel file.
Endpoint: POST /api/cg/v1/press-release/export-links/
Rate Limit: 100 requests per day per customer
Request Body:
- •
press\_releases(array, required): List of press release export items - •
id(UUID, required): Press release ID - •
channel\_ids(array of integers, optional): Specific channel IDs to export (empty = all channels)
cURL Example:
curl -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/export-links/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"press_releases": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"channel_ids": [1, 3, 5]
},
{
"id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"channel_ids": []
}
]
}'
Success Response (202 Accepted):
{
"task_id": "d4e5f6a7-b8c9-0123-def0-123456789013"
}
Task Result (After Polling):
{
"file_name": "customer_123-press_release-20250128T143022_a1b2c3d4.xlsx",
"file_url": "https://storage.googleapis.com/ca-images-persistent/customer_123-press_release-20250128T143022_a1b2c3d4.xlsx"
}
🧩 Press Release Endpoints (cont'd 11/11)
🗂️ 10. Get Press Release Channels
Retrieve all distribution channels and their media URLs for a specific press release.
Endpoint: GET /api/cg/v1/press-release/{uuid}/channels/
Path Parameters:
uuid (UUID): Press release ID
cURL Example:
curl -X GET "https://ca.searchatlas.com/api/cg/v1/press-release/550e8400-e29b-41d4-a716-446655440000/channels/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"
Success Response (200 OK):
{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"distribution": {
"id": 5,
"display_name": "TechCrunch",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/techcrunch-icon.png",
"links_approx": "3-5",
"is_coming_soon": false,
"credits_cost": 50,
"created_at": "2024-01-01T00:00:00Z"
},
"press_release": "550e8400-e29b-41d4-a716-446655440000",
"variation": "550e8400-e29b-41d4-a716-446655440000",
"media_urls": [
{
"url": "https://techcrunch.example.com/article/12345",
"hits": 0,
"indexed": true,
"last_checked_at": "2025-01-28T10:00:00Z",
"check_method": "linkgraph",
"error": null,
"batch_id": 789
},
{
"url": "https://techcrunch.example.com/article/12346",
"hits": 0,
"indexed": false,
"last_checked_at": null,
"check_method": null,
"error": null,
"batch_id": null
}
],
"indexed_media_urls": [
"https://techcrunch.example.com/article/12345"
]
},
{
"id": 2,
"distribution": {
"id": 7,
"display_name": "Forbes",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/forbes-icon.png",
"links_approx": "5-10",
"is_coming_soon": false,
"credits_cost": 75,
"created_at": "2024-01-01T00:00:00Z"
},
"press_release": "550e8400-e29b-41d4-a716-446655440000",
"variation": "7c8d9e0f-1a2b-3c4d-5e6f-7890abcdef12",
"media_urls": [
"https://forbes.example.com/sites/article-abc"
],
"indexed_media_urls": []
}
]
}
Channel Object Fields:
id: Channel ID
distribution: Distribution channel details (name, provider, cost, etc.)
press\_release: Parent press release UUID
variation: Press release variation UUID (can be the same as parent or a variation)
media\_urls: Array of URLs where content was published (with indexation metadata)
indexed\_media\_urls: Subset of URLs confirmed as indexed by search engines
📊 Distribution Endpoints
✍️ List Distributions
Get all available press release distribution channels.
Endpoint: GET /api/cg/v1/press-release/distributions/
Query Parameters:
page (integer, optional): Page number
page\_size (integer, optional): Results per page
cURL Example:
curl -X GET "https://ca.searchatlas.com/api/cg/v1/press-release/distributions/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"
Success Response (200 OK):
{
"count": 25,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"display_name": "TechCrunch",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/techcrunch-icon.png",
"links_approx": "3-5",
"is_coming_soon": false,
"credits_cost": 50,
"created_at": "2024-01-01T00:00:00Z"
},
{
"id": 2,
"display_name": "Forbes",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/forbes-icon.png",
"links_approx": "5-10",
"is_coming_soon": false,
"credits_cost": 75,
"created_at": "2024-01-01T00:00:00Z"
},
{
"id": 3,
"display_name": "Business Insider",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/business-insider-icon.png",
"links_approx": "2-4",
"is_coming_soon": false,
"credits_cost": 60,
"created_at": "2024-01-01T00:00:00Z"
},
{
"id": 10,
"display_name": "Wall Street Journal",
"provider": "SIGNAL_GENESYS",
"icon": "https://storage.googleapis.com/bucket/wsj-icon.png",
"links_approx": "10-15",
"is_coming_soon": true,
"credits_cost": 150,
"created_at": "2024-06-01T00:00:00Z"
}
]
}
Distribution Fields:
id: Distribution channel ID (use in deployment)
display\_name: Human-readable channel name
provider: Always "SIGNAL_GENESYS" (only provider currently supported)
icon: Logo/icon URL for the channel
links\_approx: Approximate number of backlinks generated
is\_coming\_soon: If true, channel is not yet available
credits\_cost: Number of credits required to use this channel
created\_at: When the distribution was added to the system
🛠️ Task Polling
Many endpoints return HTTP 202 with a task\_id. Use the Core API to poll for task completion.
Endpoint: GET /api/core/v1/tasks/{task\_id}/
cURL Example:
curl -X GET "https://ca.searchatlas.com/api/core/v1/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Response - Task Pending:
{
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "PENDING"
}
Response - Task In Progress:
{
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "STARTED"
}
Response - Task Success:
{
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "SUCCESS",
"result": {
"file_name": "customer_123-press_release-20250128T143022_a1b2c3d4.xlsx",
"file_url": "https://storage.googleapis.com/ca-images-persistent/customer_123-press_release-20250128T143022_a1b2c3d4.xlsx"
}
}
Response - Task Failed:
{
"task_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "FAILURE",
"error": "Quota exceeded: Insufficient credits for press release generation"
}
Task Statuses:
PENDING: Task queued but not started
STARTED: Task is currently executing
SUCCESS: Task completed successfully (check result field)
FAILURE: Task failed (check error field)
RETRY: Task failed but will retry automatically
Polling Strategy:
Poll every 2-5 seconds for short tasks (build, deploy)
Poll every 10-30 seconds for long tasks (export)
Stop polling after SUCCESS or FAILURE
Implement exponential backoff for production use
🧱 Error Responses
🧩 400 Bad Request
Invalid input data or validation errors.
{
"target_url": ["Invalid Target URL: URL responded with status code 404 (Not Found)"],
"target_keywords": ["This field is required."]
}
📰 401 Unauthorized
Missing or invalid authentication token.
{
"detail": "Authentication credentials were not provided."
}
📄 403 Forbidden
User does not have permission to access the resource.
{
"detail": "You do not have permission to perform this action."
}
🔗 404 Not Found
Resource does not exist.
{
"detail": "Not found."
}
📤 422 Unprocessable Entity
Business logic validation failure.
{
"detail": "Otto Project is frozen"
}
🔍 429 Too Many Requests
Rate limit exceeded.
{
"detail": "Request was throttled. Expected available in 86400 seconds."
}
📦 500 Internal Server Error
Server-side error.
{
"detail": "An error occurred while processing your request."
}
📈 Rate Limits
🔧 Press Release Export
Limit: 100 requests per day per customer
Endpoint: POST /api/cg/v1/press-release/export-links/
Response when exceeded: HTTP 429
🗂️ General API Limits
Standard rate limits apply per customer account
Contact support for rate limit increases
🧱✍️ Press Release Statuses
Draft: Created but not yet processed
Generating: AI content generation in progress
Generated: Content generated successfully
Publishing: Deployment to channels in progress
Publish Stuck: Deployment encountered issues
Publish Failed: Deployment failed permanently
Published: Successfully deployed to all channels
🔁 Workflow Examples
📰 Complete Press Release Workflow
Step 1: Create press release
PR_ID=$(curl -s -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"otto_project": 123,
"target_url": "https://example.com/product",
"target_keywords": ["AI", "innovation"],
"input_prompt": "Announce our new AI product"
}' | jq -r '.id')
echo "Created PR: $PR_ID"
Step 2: Generate content
BUILD_TASK=$(curl -s -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/$PR_ID/build/" \
-H "Authorization: Bearer $TOKEN" | jq -r '.[0]')
echo "Build task: $BUILD_TASK"
Step 3: Poll for completion
while true; do
STATUS=$(curl -s "https://ca.searchatlas.com/api/core/v1/tasks/$BUILD_TASK/" \
-H "Authorization: Bearer $TOKEN" | jq -r '.status')
if [ "$STATUS" = "SUCCESS" ]; then
echo "Build complete!"
break
elif [ "$STATUS" = "FAILURE" ]; then
echo "Build failed!"
exit 1
fi
echo "Status: $STATUS, waiting..."
sleep 5
done
Step 4: Deploy to channels
DEPLOY_TASK=$(curl -s -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/$PR_ID/deploy/signal-genesys/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"genesys_category_id": "technology",
"distribution_ids": [1, 2, 3],
"variations": true
}' | jq -r '.task_id')
echo "Deploy task: $DEPLOY_TASK"
Step 5: Export links after deployment completes
curl -X POST "https://ca.searchatlas.com/api/cg/v1/press-release/export-links/" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
"press_releases": [
{"id": "$PR_ID", "channel_ids": []}
]
}"
💡 Support & Resources
Swagger/OpenAPI Docs: https://ca.searchatlas.com/schema/swagger/
Base URL: https://ca.searchatlas.com/api/cg/v1
Support: Contact your Search Atlas account manager
API Version: v1. (stable)
❓FAQs
❓ Can I use the API without authentication?
💡 No. All requests must include a valid JWT token or API key.
❓ What happens if I send both otto_project and knowledge_graph?
⚡ The API will return a 400 Bad Request error. You must include only one.
❓ How can I check publication status in Signal Genesys?
💡 Review the signal_genesys.genesys_status field in the press release response.
The Press Release API enables teams to automate every step of their press release workflow — from creation and generation to publication and analysis.
If you need additional examples or support, our API team is here to help.