Build campaign workflows with the Swell API.
Use workspace-scoped keys for typed post, media, link, analytics, audit, and webhook integrations.
API
Use the customer REST API for typed integrations, scheduled content workflows, tracked links, analytics reads, audit logs, and webhooks.
API Quick Start
Create a key
Open Account Settings, choose API keys, and create a read/write token.
Call the API
Send the token as an Authorization bearer token to api.growonswell.com.
Use returned IDs
Use social_account_ids, media_ids, post IDs, and tracked link IDs in later calls.
Authentication
API keys belong to one workspace and can be revoked from Account Settings. Store the full key in your secret manager; Swell only shows it once.
Authorization: Bearer $SWELL_API_KEYIdempotency
Send `Idempotency-Key` on mutating `/v1` requests to make retries safe. Swell replays the original response for the same method, path, and request body, and returns 409 if the key is reused for a different request or while the first request is still running.
Idempotency-Key: import-run-2026-06-28-001Rate Limits
Successful API responses include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`. When a key is over its window, Swell returns 429 with `Retry-After`.
X-RateLimit-Remaining: 128Retry-After: 42OpenAPI Contract
The customer API publishes a filtered OpenAPI document that excludes internal app routes and includes bearer-token security metadata for the public `/v1` surface.
https://api.growonswell.com/v1/openapi.jsonView specEndpoint Reference
Workspace
/workspaceRead workspace identity, slug, timezone, and plan key for the API key.
{
"id": 42,
"object_id": "workspace_42",
"name": "Acme Growth",
"slug": "acme-growth",
"timezone": "America/New_York",
"plan_key": "growth"
}/company-profileRead the generated company profile used to ground Swell agents and automated workflows.
{
"id": 9,
"object_id": "company_profile_9",
"workspace_id": 42,
"source_urls": ["https://example.com"],
"narrative": "Acme helps growth teams understand demand, plan focused campaigns, and turn first-party signals into measurable action.",
"summary": "Acme helps launch teams understand and improve growth.",
"audience": ["Founders", "Growth operators"],
"positioning": "AI-assisted growth workspace for launch teams.",
"value_props": ["Ground content in first-party customer data"],
"feature_set": ["Social scheduling", "Attribution", "Agent workflows"],
"messaging": { "primary": "Turn workspace data into sharper growth actions." },
"tone": { "default": "Specific, pragmatic, and product-aware." },
"visual_identity": { "style": "Clean product-led visuals with clear proof points." },
"social_posture": { "linkedin": "Educational launch and growth updates." },
"source_evidence": [{ "source": "https://example.com", "detail": "Homepage positioning and product copy." }],
"confidence": 0.82,
"source_fingerprint": "a4f2...",
"stale": false,
"context": "Workspace company profile: ...",
"media": [],
"generated_at": "2026-07-09T14:00:00Z",
"created_at": "2026-07-09T13:55:00Z",
"updated_at": "2026-07-09T14:00:00Z"
}/company-profile/refreshRegenerate the company profile from source URLs, workspace data, social posture, and associated media.
{
"id": 9,
"object_id": "company_profile_9",
"workspace_id": 42,
"source_urls": ["https://example.com"],
"narrative": "Acme helps growth teams understand demand, plan focused campaigns, and turn first-party signals into measurable action.",
"summary": "Acme helps launch teams understand and improve growth.",
"audience": ["Founders", "Growth operators"],
"positioning": "AI-assisted growth workspace for launch teams.",
"value_props": ["Ground content in first-party customer data"],
"feature_set": ["Social scheduling", "Attribution", "Agent workflows"],
"messaging": { "primary": "Turn workspace data into sharper growth actions." },
"tone": { "default": "Specific, pragmatic, and product-aware." },
"visual_identity": { "style": "Clean product-led visuals with clear proof points." },
"social_posture": { "linkedin": "Educational launch and growth updates." },
"source_evidence": [{ "source": "https://example.com", "detail": "Homepage positioning and product copy." }],
"confidence": 0.82,
"source_fingerprint": "a4f2...",
"stale": false,
"context": "Workspace company profile: ...",
"media": [],
"generated_at": "2026-07-09T14:00:00Z",
"created_at": "2026-07-09T13:55:00Z",
"updated_at": "2026-07-09T14:00:00Z"
}/company-profile/sourcesReplace source URLs used for profile construction, then regenerate the profile.
{
"id": 9,
"object_id": "company_profile_9",
"workspace_id": 42,
"source_urls": ["https://example.com"],
"narrative": "Acme helps growth teams understand demand, plan focused campaigns, and turn first-party signals into measurable action.",
"summary": "Acme helps launch teams understand and improve growth.",
"audience": ["Founders", "Growth operators"],
"positioning": "AI-assisted growth workspace for launch teams.",
"value_props": ["Ground content in first-party customer data"],
"feature_set": ["Social scheduling", "Attribution", "Agent workflows"],
"messaging": { "primary": "Turn workspace data into sharper growth actions." },
"tone": { "default": "Specific, pragmatic, and product-aware." },
"visual_identity": { "style": "Clean product-led visuals with clear proof points." },
"social_posture": { "linkedin": "Educational launch and growth updates." },
"source_evidence": [{ "source": "https://example.com", "detail": "Homepage positioning and product copy." }],
"confidence": 0.82,
"source_fingerprint": "a4f2...",
"stale": false,
"context": "Workspace company profile: ...",
"media": [],
"generated_at": "2026-07-09T14:00:00Z",
"created_at": "2026-07-09T13:55:00Z",
"updated_at": "2026-07-09T14:00:00Z"
}/company-profile/mediaAssociate an existing workspace image or video with the profile as a logo, screenshot, demo, or brand reference.
{
"id": 9,
"object_id": "company_profile_9",
"workspace_id": 42,
"source_urls": ["https://example.com"],
"narrative": "Acme helps growth teams understand demand, plan focused campaigns, and turn first-party signals into measurable action.",
"summary": "Acme helps launch teams understand and improve growth.",
"audience": ["Founders", "Growth operators"],
"positioning": "AI-assisted growth workspace for launch teams.",
"value_props": ["Ground content in first-party customer data"],
"feature_set": ["Social scheduling", "Attribution", "Agent workflows"],
"messaging": { "primary": "Turn workspace data into sharper growth actions." },
"tone": { "default": "Specific, pragmatic, and product-aware." },
"visual_identity": { "style": "Clean product-led visuals with clear proof points." },
"social_posture": { "linkedin": "Educational launch and growth updates." },
"source_evidence": [{ "source": "https://example.com", "detail": "Homepage positioning and product copy." }],
"confidence": 0.82,
"source_fingerprint": "a4f2...",
"stale": false,
"context": "Workspace company profile: ...",
"media": [],
"generated_at": "2026-07-09T14:00:00Z",
"created_at": "2026-07-09T13:55:00Z",
"updated_at": "2026-07-09T14:00:00Z"
}/company-profile/media/{media_id}Remove an image or video association from the generated profile context.
{
"id": 9,
"object_id": "company_profile_9",
"workspace_id": 42,
"source_urls": ["https://example.com"],
"narrative": "Acme helps growth teams understand demand, plan focused campaigns, and turn first-party signals into measurable action.",
"summary": "Acme helps launch teams understand and improve growth.",
"audience": ["Founders", "Growth operators"],
"positioning": "AI-assisted growth workspace for launch teams.",
"value_props": ["Ground content in first-party customer data"],
"feature_set": ["Social scheduling", "Attribution", "Agent workflows"],
"messaging": { "primary": "Turn workspace data into sharper growth actions." },
"tone": { "default": "Specific, pragmatic, and product-aware." },
"visual_identity": { "style": "Clean product-led visuals with clear proof points." },
"social_posture": { "linkedin": "Educational launch and growth updates." },
"source_evidence": [{ "source": "https://example.com", "detail": "Homepage positioning and product copy." }],
"confidence": 0.82,
"source_fingerprint": "a4f2...",
"stale": false,
"context": "Workspace company profile: ...",
"media": [],
"generated_at": "2026-07-09T14:00:00Z",
"created_at": "2026-07-09T13:55:00Z",
"updated_at": "2026-07-09T14:00:00Z"
}/social-accountsList the social accounts available for programmatic content and scheduling.
[
{
"id": 123,
"object_id": "social_account_123",
"platform": "linkedin",
"handle": "acme",
"display_name": "Acme",
"status": "connected",
"external_id": "urn:li:organization:123",
"connection_type": "oauth",
"health_status": "ok",
"health_message": "",
"provider_metadata": {}
}
]Content
/postsReturn recent posts. Add status=draft, scheduled, published, failed, or archived to filter, and limit up to 200.
[
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "draft",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "draft",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}
]/postsCreate a draft with caption, tags, media IDs, social account IDs, and platform overrides.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "draft",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "draft",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}/posts/previewDry-run post validation without creating, scheduling, or publishing anything.
{
"dry_run": true,
"ready": true,
"issues": [],
"post": null
}/posts/{post_id}Read one workspace post by ID, including schedule, targets, media, tags, and publishing state.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "draft",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "draft",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}/posts/{post_id}Edit a draft or scheduled post using the same fields as the app composer.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "draft",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "draft",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}/posts/{post_id}/scheduleQueue a draft for future publishing after the same validation used in the app.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": "2026-07-02T14:30:00Z",
"status": "scheduled",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "scheduled",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:05:00Z"
}/posts/{post_id}/rescheduleMove a scheduled or failed post to a new future publish time.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": "2026-07-02T14:30:00Z",
"status": "scheduled",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "scheduled",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:05:00Z"
}/posts/{post_id}/unscheduleClear a scheduled post and return it to draft status.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "draft",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [
{
"id": 88,
"object_id": "post_target_88",
"social_account_id": 123,
"platform": "linkedin",
"caption_override": null,
"status": "draft",
"publish_result": {}
}
],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}/posts/{post_id}/archiveArchive a draft, scheduled, or failed post without deleting its history.
{
"id": 42,
"object_id": "post_42",
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"status": "archived",
"tags": ["launch", "customer-story"],
"media_ids": [301],
"targets": [],
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:10:00Z"
}Media
/mediaReturn recent images and videos that can be attached to API-created posts.
[
{
"id": 301,
"object_id": "media_301",
"filename": "media/301-launch-image.png",
"original_filename": "launch-image.png",
"content_type": "image/png",
"size_bytes": 482193,
"alt_text": "Product dashboard showing a launch report.",
"usage_count": 1,
"used_post_labels": ["Launch proof carousel"],
"last_used_at": "2026-06-28T00:00:00Z",
"url": "/v1/media/301/file",
"created_at": "2026-06-28T00:00:00Z"
}
]/mediaUpload a JPG, PNG, MP4, or MOV asset with optional alt text.
{
"id": 301,
"object_id": "media_301",
"filename": "media/301-launch-image.png",
"original_filename": "launch-image.png",
"content_type": "image/png",
"size_bytes": 482193,
"alt_text": "Product dashboard showing a launch report.",
"usage_count": 1,
"used_post_labels": ["Launch proof carousel"],
"last_used_at": "2026-06-28T00:00:00Z",
"url": "/v1/media/301/file",
"created_at": "2026-06-28T00:00:00Z"
}/media/{media_id}/fileFetch the stored media bytes for a workspace asset.
Binary response body containing the stored media file bytes.Campaigns
/linksRead tracked links with destination URLs, tracking URLs, and attribution keys.
[
{
"id": 77,
"object_id": "link_77",
"label": "Summer launch",
"destination_url": "https://example.com/summer",
"tracking_url": "https://example.com/summer?utm_source=linkedin&utm_medium=organic&utm_campaign=summer_launch&utm_content=carousel&swell_link_id=tl_summer_launch",
"post_url": "https://s.growonswell.com/r/summer-launch",
"post_id": null,
"social_account_id": 123,
"attribution_key": "tl_summer_launch",
"utm_source": "linkedin",
"utm_medium": "organic",
"utm_campaign": "summer_launch",
"utm_content": "carousel",
"tracking_params": {
"swell_link_id": "tl_summer_launch"
},
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}
]/linksCreate a campaign link with UTM fields and optional post or social account context.
{
"id": 77,
"object_id": "link_77",
"label": "Summer launch",
"destination_url": "https://example.com/summer",
"tracking_url": "https://example.com/summer?utm_source=linkedin&utm_medium=organic&utm_campaign=summer_launch&utm_content=carousel&swell_link_id=tl_summer_launch",
"post_url": "https://s.growonswell.com/r/summer-launch",
"post_id": null,
"social_account_id": 123,
"attribution_key": "tl_summer_launch",
"utm_source": "linkedin",
"utm_medium": "organic",
"utm_campaign": "summer_launch",
"utm_content": "carousel",
"tracking_params": {
"swell_link_id": "tl_summer_launch"
},
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}Analytics
/analytics/overviewRead visitors, pageviews, conversions, revenue, sources, pages, performance, and recent events.
{
"metrics": {
"visitors": 1820,
"pageviews": 6410,
"conversions": 84,
"revenue_cents": 125000
},
"top_sources": [
{
"source": "linkedin",
"medium": "organic",
"visitors": 640,
"pageviews": 2110,
"sessions": 710,
"events": 3820,
"conversions": 38,
"revenue_cents": 42000
}
],
"top_pages": [
{
"path": "/pricing",
"title": "Pricing",
"visitors": 420,
"sessions": 460,
"pageviews": 920,
"bounce_rate": 0.32,
"conversions": 21,
"revenue_cents": 21000
}
],
"traffic_series": [],
"devices": [],
"browsers": [],
"countries": [],
"web_vitals": [],
"web_vital_pages": [],
"web_vital_series": [],
"recent_events": [],
"recommendations": [],
"snippet": {
"workspace_id": 42,
"workspace_slug": "acme-growth",
"tracking_key": "swl_pk_live_...",
"script_url": "https://api.growonswell.com/swell.js",
"snippet": "<script src=\"https://api.growonswell.com/swell.js?key=swl_pk_live_...\" async></script>"
}
}/peopleRead known contacts and anonymous visitors assembled from tracking, identity calls, conversions, and trusted revenue.
[
{
"key": "contact:314",
"kind": "contact",
"contact": {
"id": 314,
"email": "jane@example.com",
"full_name": "Jane Doe",
"company": "Acme",
"lifecycle_stage": "customer",
"source": "linkedin",
"medium": "organic",
"campaign": "summer_launch",
"tags": ["trial"],
"metadata": {},
"first_seen_at": "2026-06-28T00:00:00Z",
"last_seen_at": "2026-06-29T00:00:00Z",
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-29T00:00:00Z"
},
"anonymous_id": "visitor_abc",
"display_name": "Jane Doe",
"email": "jane@example.com",
"company": "Acme",
"lifecycle_stage": "customer",
"source": "linkedin",
"medium": "organic",
"campaign": "summer_launch",
"tags": ["trial"],
"first_seen_at": "2026-06-28T00:00:00Z",
"last_seen_at": "2026-06-29T00:00:00Z",
"session_count": 3,
"event_count": 18,
"pageview_count": 9,
"conversion_count": 2,
"total_revenue_cents": 42000,
"first_url": "https://example.com/",
"first_path": "/",
"last_url": "https://example.com/pricing",
"last_path": "/pricing",
"last_title": "Pricing"
}
]/people/journeyRead a contact or visitor journey by contact_id, email, or anonymous_id, including attributed revenue totals.
{
"contact": {
"id": 314,
"email": "jane@example.com",
"full_name": "Jane Doe",
"company": "Acme",
"lifecycle_stage": "customer",
"source": "linkedin",
"medium": "organic",
"campaign": "summer_launch",
"tags": ["trial"],
"metadata": {},
"first_seen_at": "2026-06-28T00:00:00Z",
"last_seen_at": "2026-06-29T00:00:00Z",
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-29T00:00:00Z"
},
"anonymous_ids": ["visitor_abc"],
"session_count": 3,
"first_seen_at": "2026-06-28T00:00:00Z",
"last_seen_at": "2026-06-29T00:00:00Z",
"total_events": 18,
"total_revenue_cents": 42000,
"events": []
}Audit and webhooks
/audit-logRead immutable workspace audit events for API keys, public API mutations, and webhook configuration.
[
{
"id": 501,
"event_id": "audit_event_501",
"action": "post.created",
"resource_type": "post",
"resource_id": 42,
"object_id": "post_42",
"api_key_id": 12,
"metadata": {},
"created_at": "2026-06-28T00:00:00Z"
}
]/webhooksRead active and archived webhook endpoints for the workspace.
[
{
"id": 7,
"object_id": "webhook_endpoint_7",
"url": "https://example.com/swell/webhook",
"description": "Automation sink",
"events": ["audit.event.created"],
"status": "active",
"last_delivery_at": null,
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}
]/webhooksRegister an HTTPS webhook endpoint and receive its signing secret once.
{
"id": 7,
"object_id": "webhook_endpoint_7",
"url": "https://example.com/swell/webhook",
"description": "Automation sink",
"events": ["audit.event.created"],
"status": "active",
"last_delivery_at": null,
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z",
"signing_secret": "whsec_..."
}/webhooks/{endpoint_id}/archiveDisable a webhook endpoint while preserving audit and delivery history.
{
"id": 7,
"object_id": "webhook_endpoint_7",
"url": "https://example.com/swell/webhook",
"description": "Automation sink",
"events": ["audit.event.created"],
"status": "archived",
"last_delivery_at": null,
"created_at": "2026-06-28T00:00:00Z",
"updated_at": "2026-06-28T00:00:00Z"
}/webhooks/deliveriesRead pending, delivered, and failed webhook delivery records.
[
{
"id": 900,
"object_id": "webhook_delivery_900",
"endpoint_id": 7,
"event_type": "audit.event.created",
"status": "pending",
"attempt_count": 0,
"next_attempt_at": "2026-06-28T00:00:00Z",
"delivered_at": null,
"last_error": "",
"created_at": "2026-06-28T00:00:00Z"
}
]Examples
Create a draft
curl -X POST "https://api.growonswell.com/v1/posts" \
-H "Authorization: Bearer $SWELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"base_caption": "A customer story with one clear next step.",
"scheduled_at": null,
"tags": ["launch", "customer-story"],
"media_ids": [],
"social_account_ids": [123],
"platform_captions": {
"linkedin": "A customer story with one clear next step."
}
}'Upload media
curl -X POST "https://api.growonswell.com/v1/media" \
-H "Authorization: Bearer $SWELL_API_KEY" \
-F "file=@launch-image.png;type=image/png" \
-F "alt_text=A product dashboard with a clean launch report."Schedule a post
curl -X POST "https://api.growonswell.com/v1/posts/42/schedule" \
-H "Authorization: Bearer $SWELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"scheduled_at": "2026-07-02T14:30:00Z"}'Create a tracked link
curl -X POST "https://api.growonswell.com/v1/links" \
-H "Authorization: Bearer $SWELL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "Summer launch",
"destination_url": "https://example.com/summer",
"utm_source": "linkedin",
"utm_medium": "organic",
"utm_campaign": "summer_launch",
"utm_content": "carousel"
}'Errors
401 means the API key is missing, malformed, revoked, or invalid.
402 means the key owner must select a plan before making API calls.
403 means the key lacks the required scope or the key owner no longer has workspace access.
429 means the key exceeded its rate limit. Wait the number of seconds in `Retry-After` before retrying.
422 means the payload failed Swell validation, such as an unavailable social account or a past scheduled time.
