DW DiscoverWorthy API docs
.md llms.txt
Built for humans and LLMs. · Point your assistant at this page, hit Copy for LLM, or fetch the raw .md. Every type is introspectable, too.

Story Links API

Machine-to-machine API for minting customer story request links. Authenticated via managed-hosting deploy tokens (server-side only, never in a browser). Use this to programmatically invite customers to share their experience during their subscription lifecycle.

Authentication #

All requests must include your site's managed-hosting deploy token:

Shell
Authorization: Bearer <deploy_token>
# or
x-api-key: <deploy_token>

Find your deploy token in your site's Hosting settings in DiscoverWorthy (the same token used for the Business Context API).

This is a server-side credential — never expose it to clients or browsers.

Discovery #

Unauthenticated GET https://app.discoverworthy.com/api/v1/story-links returns a machine-readable discovery document listing all endpoints, auth options, and the public docs URL. No token required for this endpoint.

Endpoints #

POST https://app.discoverworthy.com/api/v1/story-links #

Mint a new story link for a customer.

Request body (JSON):

JSON
{
  "customerName": "Sarah Johnson",
  "customerCompany": "Acme Corp",
  "customerProject": "Website redesign",
  "customerEmail": "sarah@acme.com",
  "externalRef": "ORDER-12345",
  "sendEmail": true
}

Parameters:

  • customerName (required): Customer's name. ≤255 characters.
  • customerCompany (optional): Customer's company. ≤255 characters.
  • customerProject (optional): Project description. ≤255 characters.
  • customerEmail (optional): Email address for sending the invitation link. ≤255 characters.
  • externalRef (optional): Your internal reference number (order ID, subscription ID, etc.). ≤255 characters.
  • sendEmail (optional): If true and customerEmail is provided, automatically send the invitation. Default: false.

Response (201):

JSON
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "token": "csr_550e8400e29b41d4a716446655440000",
  "url": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
  "status": "pending",
  "expiresAt": "2026-08-13T12:00:00Z",
  "externalRef": "ORDER-12345",
  "emailSent": true,
  "links": {
    "story": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
    "status": "https://app.discoverworthy.com/api/v1/story-links/csr_550e8400e29b41d4a716446655440000"
  }
}

Rate limiting:

Each site has a daily cap (default: 50 story links). Minting beyond the cap returns 429 Too Many Requests.

GET https://app.discoverworthy.com/api/v1/story-links #

List story requests for your site.

Query parameters:

  • externalRef (optional): Filter by external reference (the order/ref number you provided when minting).
  • status (optional): Filter by stored status: pending, completed, cancelled, or expired. (viewed is derived — viewed-but-unsubmitted links are stored as pending and returned with status: "viewed".)
  • limit (optional): Results per page. 1–100, default 50.

Response:

JSON
{
  "requests": [
    {
      "token": "csr_550e8400e29b41d4a716446655440000",
      "status": "viewed",
      "customerName": "Sarah Johnson",
      "customerCompany": "Acme Corp",
      "customerProject": "Website redesign",
      "externalRef": "ORDER-12345",
      "rating": null,
      "createdAt": "2026-07-14T12:00:00Z",
      "viewedAt": "2026-07-14T13:00:00Z",
      "completedAt": null,
      "expiresAt": "2026-08-13T12:00:00Z",
      "emailSent": true,
      "url": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000"
    }
  ]
}

GET https://app.discoverworthy.com/api/v1/story-links/[token] #

Get status and completed story for a single link.

Response (if in progress):

JSON
{
  "token": "csr_550e8400e29b41d4a716446655440000",
  "status": "pending",
  "customerName": "Sarah Johnson",
  "customerCompany": "Acme Corp",
  "customerProject": "Website redesign",
  "externalRef": "ORDER-12345",
  "rating": null,
  "createdAt": "2026-07-14T12:00:00Z",
  "viewedAt": null,
  "completedAt": null,
  "expiresAt": "2026-08-13T12:00:00Z",
  "emailSent": true,
  "url": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
  "story": null,
  "links": {
    "story": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
    "dashboard": "https://app.discoverworthy.com/your-org/case-studies"
  }
}

Response (if completed):

JSON
{
  "token": "csr_550e8400e29b41d4a716446655440000",
  "status": "completed",
  "customerName": "Sarah Johnson",
  "customerCompany": "Acme Corp",
  "customerProject": "Website redesign",
  "externalRef": "ORDER-12345",
  "rating": 9,
  "createdAt": "2026-07-14T12:00:00Z",
  "viewedAt": "2026-07-14T13:00:00Z",
  "completedAt": "2026-07-14T14:00:00Z",
  "expiresAt": "2026-08-13T12:00:00Z",
  "emailSent": true,
  "url": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
  "story": {
    "title": "How Acme Corp increased conversions by 40%",
    "summary": "Sarah shares how the website redesign drove more leads.",
    "challenge": "Outdated site design, poor mobile experience.",
    "solution": "Complete redesign with modern UX and conversion optimizations.",
    "results": "40% increase in conversions, 2x more leads.",
    "testimonial": "The results exceeded our expectations.",
    "testimonialAuthor": "Sarah Johnson",
    "testimonialRole": "Marketing Director",
    "keyMetrics": [
      { "label": "Conversion increase", "value": "40", "unit": "%" },
      { "label": "Lead volume", "value": "2", "unit": "x" }
    ],
    "tags": ["design", "conversion", "website"],
    "servicesUsed": ["UI/UX Design", "Development"],
    "publishStatus": "draft"
  },
  "links": {
    "story": "https://app.discoverworthy.com/story/csr_550e8400e29b41d4a716446655440000",
    "dashboard": "https://app.discoverworthy.com/your-org/case-studies"
  }
}

DELETE https://app.discoverworthy.com/api/v1/story-links/[token] #

Rescind a story link (e.g., when the customer's subscription is cancelled). Only pending links can be rescinded.

Response:

JSON
{
  "message": "Story link rescinded."
}

Status Lifecycle #

Story links follow this lifecycle:

Status Meaning
pending Link minted, customer has not yet visited it.
viewed Customer clicked the link and started the interview, but did not submit.
completed Customer submitted their story. A draft case study is created in your DiscoverWorthy dashboard.
cancelled Link was rescinded (e.g., order cancelled). No longer usable.
expired Link was not used within 30 days.

The story remains a draft in your dashboard (publishStatus: "draft") until you review and publish it.

Workflow Example #

Order-fulfillment integration:

Shell
# 1. Order placed
curl -X POST https://app.discoverworthy.com/api/v1/story-links \
  -H "Authorization: Bearer <deploy_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "customerName": "Jane Doe",
    "customerEmail": "jane@example.com",
    "externalRef": "ORD-98765",
    "sendEmail": true
  }'

# Save the token returned: "csr_123abc..."

# 2. Poll status periodically (or in your post-fulfillment flow)
curl -X GET "https://app.discoverworthy.com/api/v1/story-links/csr_123abc..." \
  -H "Authorization: Bearer <deploy_token>"

# Check response.status:
# - "completed" → story is ready; review in dashboard and publish
# - "pending" / "viewed" → still waiting for customer
# - "expired" → customer did not respond; consider re-minting or follow-up email

# 3. Order cancelled?
curl -X DELETE "https://app.discoverworthy.com/api/v1/story-links/csr_123abc..." \
  -H "Authorization: Bearer <deploy_token>"

Notes #

  • The completed story is created as a draft case study in your DiscoverWorthy dashboard. You review, edit, and publish it manually in the dashboard's case-studies section (or use the dashboard link provided in the response).
  • The customer is guided through a short conversational interview on a branded page — no login or account required on their side.
  • Links expire after 30 days and cannot be renewed via the API; mint a new link if needed.
  • Daily cap is configurable per environment (default: 50 links/site/day).