---
openapi: 3.0.1
info:
  title: Storydoc API V2
  description: |-
    # Overview
    The Storydoc API V2 provides capabilities for automating Storydoc version creation and management. Create personalized versions of your Storydoc templates with custom data, password protection, and gated content.

    ## Key Features
    - **Version Management**: Create and update personalized versions of your Storydoc templates
    - **Dynamic Variables**: Support for text, numbers, links, dates, arrays, and logo variables
    - **Access Control**: Password protection and gated content forms

    ## Rate Limits
    **Version Endpoints**: 150 requests per minute per IP address

    **Rate Limit Headers**: Every response includes the following headers to help you monitor usage:
    - `x-rate-limit-counter`: Current number of requests made
    - `x-rate-limit-maximum`: Maximum allowed requests per minute

    **Rate Limit Exceeded**: When the limit is exceeded, you'll receive a 429 status code with the error message "Too many requests". Wait for the rate limit window to reset before making additional requests.
  contact:
    email: support@storydoc.com
  version: 2.1.0
tags:
- name: versions
  description: Manage story versions
- name: account
  description: Account/Organization information
- name: stories
  description: Manage and retrieve stories
- name: analytics
  description: Query engagement analytics
security:
- bearerAuth: []
servers:
- url: https://api.storydoc.com
  description: Production API server
paths:
  "/v2/versions":
    post:
      tags:
      - versions
      summary: Create a new story version
      description: Creates a personalized version of an existing story template with
        custom data. Each version gets a unique URL and can be tracked independently.
      operationId: createStoryVersion
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateVersionRequest"
            examples:
              simple:
                summary: 1. Simple Version
                description: Basic personalized version with just the required fields
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: Sales Presentation for ACME Corp
                    company: ACME Corporation
                    first_name: John
                    last_name: Doe
              withAutomatedLogo:
                summary: 2. Automated Logo Generation
                description: Automatically fetch and apply company logos based on
                  domain
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: Partnership Proposal
                    company: ACME Corporation
                    first_name: John
                    last_name: Doe
                    partner_logo:
                      theme: dark
                      domain: microsoft.com
              withExpiry:
                summary: 3. Time-Limited Version
                description: Version that automatically expires after 30 days
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  daysToExpire: 30
                  data:
                    title: Sales Presentation for ACME Corp
                    company: ACME Corporation
                    first_name: John
                    last_name: Doe
              withPassword:
                summary: 4. Password Protected
                description: Secure version requiring password access
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: Sales Presentation for ACME Corp
                    company: ACME Corporation
                    first_name: John
                    last_name: Doe
                    password: SecurePass123
              withGatedContent:
                summary: 5. Lead Capture Form
                description: Collect visitor information before showing content
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: Product Demo - Lead Generation
                    company: ACME Corporation
                    offer: Free 30-day trial included
                    gatedContent:
                      gatedContent: true
                      name: true
                      nameRequired: true
                      logo: true
                      logoSRC: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
                      title: Get instant access to our product demo
              withArrayOfObjects:
                summary: 6. Dynamic Data Lists
                description: Version with product catalogs, pricing tables, or team
                  rosters
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: 2025 Product Catalog
                    company: ACME Corporation
                    launch_date: January 2025
                    products:
                    - name: Enterprise Suite
                      price: 15000
                      custom_field1: 24/7 Support
                    - name: Professional Plan
                      price: 3000
                      custom_field1: Business Hours Support
                    - name: Starter Package
                      price: 500
                      custom_field1: Email Support
                    team_contacts:
                    - name: Sarah Johnson
                      role: Sales Director
                      email: sarah@acme.com
                    - name: Mike Chen
                      role: Product Manager
                      email: mike@acme.com
              withPreviewImage:
                summary: 7. Set Thumbnail
                description: Set a custom preview thumbnail image for the version
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  data:
                    title: Visual Impact Report
                    company: ACME Corporation
                    tagline: Results that speak for themselves
                    highlight: 300% ROI in 6 months
                    ogImage: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
              completeExample:
                summary: 8. Complete Example
                description: 'Comprehensive example combining all features: expiration,
                  password protection, gated content, arrays, and custom preview'
                value:
                  storyId: 61b1e50223b713000a41ca74
                  senderEmail: sender@company.com
                  daysToExpire: 30
                  data:
                    title: Enterprise Sales Proposal - Q1 2025
                    company: ACME Corporation
                    first_name: John
                    last_name: Doe
                    email: john.doe@acme.com
                    phone: "+1-555-0123"
                    date: January 15, 2025
                    password: SecureProposal2025
                    ogImage: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
                    logo1:
                      domain: acme.com
                      theme: dark
                    products:
                    - name: Enterprise Suite
                      price: 15000
                      features: Unlimited users, 24/7 support
                      discount: 20%
                    - name: Professional Plan
                      price: 3000
                      features: 50 users, Business hours support
                      discount: 10%
                    - name: Starter Package
                      price: 500
                      features: 10 users, Email support
                      discount: 5%
                    team_contacts:
                    - name: Sarah Johnson
                      role: Sales Director
                      email: sarah@acme.com
                      phone: "+1-555-0124"
                    - name: Mike Chen
                      role: Product Manager
                      email: mike@acme.com
                      phone: "+1-555-0125"
                    milestones:
                    - phase: Discovery
                      timeline: Week 1-2
                      deliverable: Requirements document
                    - phase: Implementation
                      timeline: Week 3-6
                      deliverable: System deployment
                    - phase: Training
                      timeline: Week 7-8
                      deliverable: User certification
                    gatedContent:
                      gatedContent: true
                      name: true
                      nameRequired: true
                      logo: true
                      logoSRC: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
                      title: Get instant access to your personalized enterprise proposal
                    custom_field_1: Premium Support Included
                    custom_field_2: ROI Calculator Available
                    custom_field_3: Free 30-day Trial
      responses:
        '200':
          description: Version created successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VersionResponse"
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error400"
              examples:
                missingTitle:
                  summary: Missing data.title
                  description: The required title field is missing from the data object
                  value:
                    error: Missing data.title in request body.
                senderNotFound:
                  summary: Sender email not found
                  description: The sender email is not registered in the organization
                  value:
                    error: senderEmail email@domain.com not found in this organization
                storyNotFound:
                  summary: Story not found
                  description: The specified story ID does not exist
                  value:
                    error: Story 67c8451e37c1f5065165c08b3 not found.
                storyNotLive:
                  summary: Story not published
                  description: The story exists but has not been published yet
                  value:
                    error: Story status is not Live, click Share to set it to Live,
                      https://editor.storydoc.com/pages/editor/6776560c218435d60586da69
        '403':
          description: Authentication failed or token outdated
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
  "/v2/versions/{versionId}":
    post:
      tags:
      - versions
      summary: Update an existing version
      description: Updates the data in an existing version. Use the force parameter
        to override versions that have been manually edited.
      operationId: updateStoryVersion
      parameters:
      - name: versionId
        in: path
        required: true
        description: The ID of the version to update
        schema:
          type: string
          example: 61b1f40a3a86b7a96d0d8ccc
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/UpdateVersionRequest"
            example:
              senderEmail: sender@company.com
              data:
                title: Updated Sales Presentation
                company: ACME Corporation
                first_name: John
                last_name: Doe
      responses:
        '200':
          description: Version updated successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/VersionResponse"
        '400':
          description: Invalid request or version not editable
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error400"
              examples:
                missingTitle:
                  summary: Missing data.title
                  description: The required title field is missing from the data object
                  value:
                    error: Missing data.title in request body.
                senderNotFound:
                  summary: Sender email not found
                  description: The sender email is not registered in the organization
                  value:
                    error: senderEmail email@domain.com not found in this organization
                versionNotEditable:
                  summary: Version not editable
                  description: The version has been manually edited and cannot be
                    updated without force flag
                  value:
                    error: The version has been edited. Use force=true to override
                      the changes.
        '403':
          description: Authentication failed or token outdated
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
        '404':
          description: Version not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
  "/v2/account":
    get:
      tags:
      - account
      summary: Get account details
      description: Retrieves basic information about the authenticated account/organization
      operationId: getAccount
      responses:
        '200':
          description: Account details retrieved successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/AccountResponse"
              example:
                orgId: 60d5eca77a2d1a001c4d9f7e
                title: ACME Corporation
        '403':
          description: Authentication failed or missing token
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
              example:
                error: Missing authorization token
        '404':
          description: Account not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
              example:
                error: Account not found.
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
  "/v2/stories/{storyId}":
    get:
      tags:
      - stories
      summary: Get story details
      description: Retrieves detailed information about a specific story including
        its settings and dynamic variables
      operationId: getStory
      parameters:
      - name: storyId
        in: path
        required: true
        description: The ID of the story to retrieve
        schema:
          type: string
          example: 61b1e50223b713000a41ca74
      responses:
        '200':
          description: Story details retrieved successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/StoryResponse"
              example:
                id: 61b1e50223b713000a41ca74
                status: Live
                previewUrl: https://view.storydoc.com/preview/abc123
                createdAt: '2024-01-15T10:30:00.000Z'
                title: Sales Presentation Template
                dynamicVariables:
                  first_name:
                    type: input
                    name: first_name
                    title: Prospect's first name
                    default: ''
                    tip: Prospect's first name
                    validation:
                      required: true
                      errorMessage: Required
                    mapping: FirstName
                  company:
                    type: input
                    name: company
                    title: Company name
                    default: ''
                    tip: Enter the company name
                    validation:
                      required: false
                    mapping: CompanyName
        '400':
          description: Missing or invalid storyId parameter
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error400"
              example:
                error: Missing storyId
        '403':
          description: Authentication failed or missing token
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
              example:
                error: Access denied
        '404':
          description: Story not found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
              example:
                error: Story not found
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
  "/v2/stories":
    get:
      tags:
      - stories
      summary: List all stories
      description: Retrieves a list of all stories in the organization with optional
        status filtering
      operationId: getStories
      parameters:
      - name: status
        in: query
        required: false
        description: Filter stories by status
        schema:
          type: string
          enum:
          - Draft
          - Live
          - Archived
          example: Live
      responses:
        '200':
          description: Stories retrieved successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  "$ref": "#/components/schemas/StoryResponse"
              example:
              - id: 61b1e50223b713000a41ca74
                status: Live
                previewUrl: https://view.storydoc.com/preview/abc123
                createdAt: '2024-01-15T10:30:00.000Z'
                title: Sales Presentation Template
                dynamicVariables:
                  first_name:
                    type: input
                    name: first_name
                    title: Prospect's first name
                    default: ''
                    tip: Prospect's first name
                    validation:
                      required: true
                      errorMessage: Required
                    mapping: FirstName
                  company:
                    type: input
                    name: company
                    title: Company name
                    default: ''
                    tip: Enter the company name
                    validation:
                      required: false
                    mapping: CompanyName
              - id: 61b1e50223b713000a41ca75
                status: Draft
                previewUrl:
                createdAt: '2024-01-20T14:45:00.000Z'
                title: Product Demo Template
                dynamicVariables:
                  product_name:
                    type: input
                    name: product_name
                    title: Product Name
                    default: ''
                    tip: Enter the product name
                    validation:
                      required: true
                      errorMessage: Product name is required
                    mapping: ProductName
                  features:
                    type: array
                    name: features
                    title: Product Features
                    default: []
                    tip: List of product features
                    validation:
                      required: false
                    mapping: Features
        '403':
          description: Authentication failed or missing token
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
              example:
                error: Access denied
        '404':
          description: No stories found
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
              example:
                error: Stories not found
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
  "/v2/stories/generate":
    post:
      tags:
      - stories
      summary: Generate a new story from a prompt
      description: |-
        Generates a brand-new presentation from a natural-language prompt using AI. The endpoint runs a 3-step pipeline (outline → slide layouts → per-slide content), optionally derives a brand color palette and fonts from the supplied `website`, persists the page in **Live** status, and creates its live link.

        The response includes the live URL, short URL, editor URL, and the `pageId` / `versionId` you can pass to other v2 endpoints (e.g. use `pageId` as `storyId` in `POST /v2/versions` to create personalized variants of the generated story).

        ## Rate Limit
        150 requests per minute per organization. Every response includes `x-rate-limit-counter` and `x-rate-limit-maximum` headers.

        ## Latency
        Generation is synchronous and typically takes 30–90 seconds depending on slide count and brand pipeline. Use a long-running HTTP client and set a generous read timeout (≥ 180s).
      operationId: generateStory
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/GenerateStoryRequest"
            examples:
              minimal:
                summary: 1. Minimal request
                description: Only the required fields — the generator picks a default
                  presentation type and skips the brand pipeline.
                value:
                  prompt: A sales deck pitching our analytics product to enterprise
                    marketing teams. Highlight ROI, ease of integration, and customer
                    success stories.
                  senderEmail: sender@company.com
              withBrand:
                summary: 2. With brand context
                description: Supplying `company` and `website` lets the generator
                  fetch brand colors, fonts, and logo via Brandfetch + website scrape
                  and apply them to the story's design system. If the brand pipeline
                  fails or returns unusable data, the story falls back to scaffold
                  defaults (no error).
                value:
                  prompt: 'A pitch deck for our seed round: founding team, the problem,
                    our unique solution, traction, and the ask.'
                  senderEmail: sender@company.com
                  company: ACME Corporation
                  website: acme.com
              withPresentationType:
                summary: 3. With a specific presentation type
                description: "`presentation type` selects an AI template tuned for
                  that document class. Must be one of the supported classifications
                  — see the enum on `GenerateStoryRequest`."
                value:
                  prompt: 'Quarterly business review for our key enterprise account:
                    revenue trends, product adoption, support metrics, and roadmap
                    for next quarter.'
                  senderEmail: sender@company.com
                  company: ACME Corporation
                  website: https://acme.com
                  presentation type: Quarterly Business Review
      responses:
        '200':
          description: Story generated and published successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/GenerateStoryResponse"
              example:
                url: https://www.storydoc.com/5d7d8922e00d9265/2e91b144-092f-456b-8f2e-0bae9f7f3355
                shortUrl: https://view.storydoc.com/4GdDGt
                pageId: 672a1c50223b713000a41ca74
                versionId: 672a1f40a3a86b7a96d0d8ccc
                editorUrl: https://app.storydoc.com/pages/editor/672a1c50223b713000a41ca74/672a1f40a3a86b7a96d0d8ccc
                versionUrl: https://app.storydoc.com/pages/editor/672a1c50223b713000a41ca74/versions/672a1f40a3a86b7a96d0d8ccc
        '400':
          description: Invalid request body or unsupported presentation type
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error400"
              examples:
                missingPrompt:
                  summary: Missing or empty prompt
                  value:
                    error: Missing or empty "prompt" in request body
                invalidSender:
                  summary: Missing or invalid senderEmail
                  value:
                    error: Missing or invalid "senderEmail" in request body
                senderNotInOrg:
                  summary: Sender email not in organization
                  value:
                    error: senderEmail "sender@company.com" not found in this organization
                invalidPresentationType:
                  summary: Unsupported presentation type
                  description: When the supplied `presentation type` is not in the
                    allowed list, the response body includes the full list under `allowedPresentationTypes`.
                  value:
                    error: Invalid "presentation type". Must be one of the supported
                      classifications.
                    allowedPresentationTypes:
                    - Agency pitch deck
                    - Sales deck
                    - Quarterly Business Review
                    - "..."
                invalidTokenOrgId:
                  summary: Token missing orgId
                  value:
                    error: 'Invalid token: missing orgId'
        '403':
          description: Missing or invalid authorization token
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
              examples:
                missingToken:
                  summary: Missing token
                  value:
                    error: Missing authorization token
                invalidToken:
                  summary: Invalid or expired token
                  value:
                    error: Access denied
        '404':
          description: Account not found for the authenticated organization
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
              example:
                error: Account not found
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests per minute
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Generation pipeline failed
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
              example:
                error: Failed to generate story
                errorId: a1b2c3d4e5f60718
  "/v2/analytics/events":
    get:
      tags:
      - analytics
      summary: Query analytics events
      description: |-
        Returns paginated raw engagement events (views and clicks) for the authenticated organization, filtered by date range and optional storyId / versionId / userEmail.

        ## Plan
        This endpoint is available on the **Team** plan only.

        ## Date Range
        Both `dateFrom` and `dateTo` are required ISO 8601 strings. The `dateTo` boundary is inclusive (events on the supplied day are returned). The maximum range is 92 days (3 months).

        ## Pagination
        Results are paginated with a fixed page size of 1000. Pages are 1-indexed. Use the `pagination.hasMore` flag to determine whether to request the next page.

        ## Filtering by user
        Pass `userEmail` to restrict results to events on versions created by that user. The email is resolved to a user in the authenticated organization before querying.
      operationId: getAnalyticsEvents
      parameters:
      - name: dateFrom
        in: query
        required: true
        description: Inclusive start of the date range (ISO 8601, UTC)
        schema:
          type: string
          format: date-time
          example: '2026-01-01T00:00:00Z'
      - name: dateTo
        in: query
        required: true
        description: Inclusive end of the date range (ISO 8601, UTC). Must be at most
          92 days after dateFrom.
        schema:
          type: string
          format: date-time
          example: '2026-03-31T23:59:59Z'
      - name: storyId
        in: query
        required: false
        description: Restrict events to a single story
        schema:
          type: string
          example: 61b1e50223b713000a41ca74
      - name: versionId
        in: query
        required: false
        description: Restrict events to a single version
        schema:
          type: string
          example: 65a1e50223b713000a41ca99
      - name: userEmail
        in: query
        required: false
        description: Restrict events to versions created by the user with this email.
          Must match a user in the authenticated organization.
        schema:
          type: string
          format: email
          example: sender@company.com
      - name: page
        in: query
        required: false
        description: 1-indexed page number. Defaults to 1.
        schema:
          type: integer
          minimum: 1
          default: 1
          example: 1
      responses:
        '200':
          description: Events retrieved successfully
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/AnalyticsEventsResponse"
        '400':
          description: Invalid request (missing/invalid params, range > 3 months,
            invalid token, etc.)
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error400"
              examples:
                missingDates:
                  summary: Missing required dates
                  value:
                    error: dateFrom and dateTo are required (ISO 8601, e.g. 2026-01-01
                      or 2026-01-01T00:00:00Z)
                rangeTooLarge:
                  summary: Date range exceeds 3 months
                  value:
                    error: Date range cannot exceed 3 months
                invalidEmail:
                  summary: Invalid userEmail
                  value:
                    error: userEmail must be a valid email address
                tokenRevoked:
                  summary: API token revoked
                  value:
                    error: Token has been revoked
        '403':
          description: Authentication failed, missing token, or account is not on
            the Team plan
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error403"
              examples:
                missingToken:
                  summary: Missing or invalid token
                  value:
                    error: Access denied
                notTeamPlan:
                  summary: Account is not on the Team plan
                  value:
                    error: Analytics API is available on the Team plan only
        '404':
          description: userEmail does not match any user in the organization
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error404"
              example:
                error: userEmail sender@company.com not found in this organization
        '429':
          description: Rate limit exceeded
          headers:
            x-rate-limit-counter:
              description: Current request count
              schema:
                type: integer
            x-rate-limit-maximum:
              description: Maximum allowed requests per minute
              schema:
                type: integer
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error429"
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/Error500"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |-
        JWT Bearer token authentication in the Authorization header using the format: `Bearer <your-jwt-token>`.

        **Note:** Applicable for Storydoc subscription plans that have API access.

        **Getting Your API Key:**
        1. Log into your Storydoc account
        2. Navigate to the [Integrations page](https://editor.storydoc.com/pages/profile/integrations?tab=automations)
        3. Go to the "Automations" tab
        4. Copy your API key from the displayed token

        If you encounter authentication errors, you may need to regenerate your token from the integrations page.
  schemas:
    CreateVersionRequest:
      type: object
      required:
      - storyId
      - senderEmail
      - data
      properties:
        storyId:
          type: string
          description: 'The ID of the story template. Extract this from your Storydoc
            editor URL: https://editor.storydoc.com/pages/editor/{storyId}'
          example: 61b1e50223b713000a41ca74
        senderEmail:
          type: string
          format: email
          description: Email of the sender (must exist in organization)
          example: john.doe@company.com
        daysToExpire:
          type: integer
          description: Number of days until version expires. Omit for permanent/public
            version
          minimum: 1
          example: 30
        data:
          "$ref": "#/components/schemas/VersionData"
    UpdateVersionRequest:
      type: object
      required:
      - senderEmail
      - data
      properties:
        senderEmail:
          type: string
          format: email
          description: Email of the sender (must exist in organization)
          example: john.doe@company.com
        force:
          type: boolean
          description: Force update even if version has been manually edited
          default: false
          example: false
        data:
          "$ref": "#/components/schemas/VersionData"
    VersionData:
      type: object
      required:
      - title
      properties:
        title:
          type: string
          description: Title of the version (required)
          example: Sales Proposal - ACME Corporation
        first_name:
          type: string
          example: John
        last_name:
          type: string
          example: Doe
        company:
          type: string
          example: ACME Corporation
        email:
          type: string
          format: email
          example: john.doe@acme.com
        phone:
          type: string
          example: "+1-555-0123"
        date:
          type: string
          description: Date in any format
          example: January 15, 2025
        products:
          type: array
          description: Array of product objects
          items:
            type: object
            properties:
              name:
                type: string
                example: Enterprise Suite
              price:
                type: number
                example: 15000
        gatedContent:
          "$ref": "#/components/schemas/GatedContent"
        password:
          type: string
          description: Password required to view the version
          example: SecurePass123
        ogImage:
          type: string
          format: uri
          description: Open Graph preview image URL for the version
          example: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
        logo:
          "$ref": "#/components/schemas/LogoVariable"
          description: Logo configuration for automatic logo fetching
          example:
            theme: dark
            domain: microsoft.com
      additionalProperties: true
      example:
        title: Sales Presentation
        company: ACME Corp
        custom_field_1: Any value
        custom_field_2: 12345
        logo:
          domain: acme.com
          theme: dark
        partner_logo:
          domain: microsoft.com
          theme: light
    GatedContent:
      type: object
      description: Gated content configuration for access control
      properties:
        gatedContent:
          type: boolean
          description: Enable/disable content gating
          example: true
        name:
          type: boolean
          description: Show name field in the gate form
          example: true
        nameRequired:
          type: boolean
          description: Make name field required
          example: true
        logo:
          type: boolean
          description: Show logo on the gate form
          example: true
        logoSRC:
          type: string
          format: uri
          description: URL of the logo to display on the gate form
          example: https://www.storydoc.com/assets/images/branding/og-storydoc.gif
        title:
          type: string
          description: Custom message shown on the gate form
          example: Please fill in the information below to view your proposal.
    LogoVariable:
      type: object
      description: Logo configuration object
      required:
      - domain
      properties:
        domain:
          type: string
          description: Domain to fetch logo from
          example: acme.com
        theme:
          type: string
          description: Logo theme preference
          enum:
          - dark
          - light
          default: dark
          example: dark
    VersionResponse:
      type: object
      properties:
        url:
          type: string
          format: uri
          description: Public URL for the version
          example: https://www.storydoc.com/5d7d8922e00d9265/2e91b144-092f-456b-8f2e-0bae9f7f3355
        shortUrl:
          type: string
          format: uri
          description: Shortened URL for the version
          example: https://view.storydoc.com/4GdDGt
        editorUrl:
          type: string
          format: uri
          description: URL to edit the version in Storydoc editor
          example: https://app.storydoc.com/pages/editor/61b1e50223b713000a41ca74/61b1f40a3a86b7a96d0d8ccc
        versionUrl:
          type: string
          format: uri
          description: URL to view version details in Storydoc platform
          example: https://app.storydoc.com/pages/editor/61b1e50223b713000a41ca74/versions/61b1f40a3a86b7a96d0d8ccc
        versionId:
          type: string
          description: Unique identifier for the version (only in create response)
          example: 61b1f40a3a86b7a96d0d8ccc
    AccountResponse:
      type: object
      properties:
        orgId:
          type: string
          description: Unique identifier for the organization/account
          example: 60d5eca77a2d1a001c4d9f7e
        title:
          type: string
          description: Name of the organization/account
          example: ACME Corporation
      required:
      - orgId
      - title
    StoryResponse:
      type: object
      properties:
        id:
          type: string
          description: Unique identifier for the story
          example: 61b1e50223b713000a41ca74
        status:
          type: string
          description: Current status of the story
          enum:
          - Draft
          - Live
          - Archived
          example: Live
        previewUrl:
          type: string
          format: uri
          nullable: true
          description: Preview URL for the story (null if not published)
          example: https://view.storydoc.com/preview/abc123
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the story was created
          example: '2024-01-15T10:30:00.000Z'
        title:
          type: string
          description: Title of the story
          example: Sales Presentation Template
        dynamicVariables:
          type: object
          description: Dynamic variables configuration for the story
          additionalProperties:
            type: object
            properties:
              type:
                type: string
                description: Type of the variable
                example: input
              name:
                type: string
                description: Variable name
                example: first_name
              title:
                type: string
                description: Display title for the variable
                example: Prospect's first name
              default:
                type: string
                description: Default value
                example: ''
              tip:
                type: string
                description: Tooltip or help text
                example: Prospect's first name
              validation:
                type: object
                properties:
                  required:
                    type: boolean
                    example: true
                  errorMessage:
                    type: string
                    example: Required
              mapping:
                type: string
                description: Field mapping
                example: FirstName
          example:
            first_name:
              type: input
              name: first_name
              title: Prospect's first name
              default: ''
              tip: Prospect's first name
              validation:
                required: true
                errorMessage: Required
              mapping: FirstName
            company:
              type: input
              name: company
              title: Company name
              default: ''
              tip: Enter the company name
              validation:
                required: false
              mapping: CompanyName
      required:
      - id
      - status
      - title
    GenerateStoryRequest:
      type: object
      required:
      - prompt
      - senderEmail
      properties:
        prompt:
          type: string
          description: Natural-language description of the presentation you want to
            generate. The more concrete the prompt (topic, audience, structure, tone,
            key points), the better the output. Cannot be empty or whitespace-only.
          example: A 6-slide sales deck pitching our analytics product to enterprise
            marketing teams. Highlight ROI, ease of integration, and customer success
            stories.
        senderEmail:
          type: string
          format: email
          description: Email of the user that owns the generated story (becomes the
            story creator and the sender on the live link). Must belong to a user
            in the authenticated organization, otherwise the request is rejected with
            400.
          example: sender@company.com
        company:
          type: string
          description: Optional company name to use as the subject of the presentation.
            If omitted and `website` is provided, the name is inferred from Brandfetch.
          example: ACME Corporation
        website:
          type: string
          description: Optional company website used to derive brand colors, fonts,
            and logo for the generated story's design system. Accepts a bare domain
            (`acme.com`) or a full URL (`https://acme.com/about`); the hostname is
            extracted automatically. If the brand pipeline fails or returns unusable
            data, the story falls back to scaffold defaults (the request still succeeds).
          example: acme.com
        presentation type:
          type: string
          description: Optional classification that selects an AI template tuned for
            that document class. Must be one of the supported subtypes (see enum).
            Defaults to `General presentation` when omitted. Unsupported values return
            400 with the full allowed list under `allowedPresentationTypes`.
          default: General presentation
          enum:
          - Agency pitch deck
          - Annual report
          - Brand guidelines
          - Brand proposal
          - Brochure
          - Business Plan
          - Business report
          - Case study one-pager
          - Company presentation
          - Construction proposal
          - Customer onboarding meeting
          - E-book
          - ESG report
          - Event proposal
          - Film pitch deck
          - Gaming pitch deck
          - General presentation
          - HR recruitment
          - Invest pitch deck
          - Investor report
          - Marketing case study
          - Marketing plan
          - Marketing proposal
          - Music event sponsorship proposal
          - NGO report
          - New employee onboarding
          - One pager
          - Partnership proposal
          - Pre-interview deck
          - Product launch
          - Product newsletter
          - Product pitch deck
          - Product roadmap
          - Project proposal
          - Quarterly Business Review
          - Quarterly report
          - Real estate listing
          - Research report
          - Restaurant proposal deck
          - Sales deck
          - Sales kickoff meeting
          - Sales proposal
          - Service pitch deck
          - Sports sponsorship
          - Startup pitch deck
          - Student case study
          - Student report
          - Video case study
          - Webinar
          - White paper
          - Workshop proposal
          example: Sales deck
    GenerateStoryResponse:
      type: object
      required:
      - url
      - shortUrl
      - pageId
      - versionId
      - editorUrl
      - versionUrl
      properties:
        url:
          type: string
          format: uri
          description: Public live URL of the generated story.
          example: https://www.storydoc.com/5d7d8922e00d9265/2e91b144-092f-456b-8f2e-0bae9f7f3355
        shortUrl:
          type: string
          format: uri
          description: Shortened share URL for the live link.
          example: https://view.storydoc.com/4GdDGt
        pageId:
          type: string
          description: ID of the underlying story (page). Use this as `storyId` in
            subsequent `POST /v2/versions` calls to create personalized variants of
            the generated story.
          example: 672a1c50223b713000a41ca74
        versionId:
          type: string
          description: ID of the generated live link. Use it as the path parameter
            for `POST /v2/versions/{versionId}` to update its data.
          example: 672a1f40a3a86b7a96d0d8ccc
        editorUrl:
          type: string
          format: uri
          description: Deep link to edit the generated version in the Storydoc editor.
          example: https://app.storydoc.com/pages/editor/672a1c50223b713000a41ca74/672a1f40a3a86b7a96d0d8ccc
        versionUrl:
          type: string
          format: uri
          description: Deep link to the version detail page in the Storydoc platform.
          example: https://app.storydoc.com/pages/editor/672a1c50223b713000a41ca74/versions/672a1f40a3a86b7a96d0d8ccc
    AnalyticsEventRow:
      type: object
      properties:
        sessionId:
          type: string
          nullable: true
          example: 1c2f0c2c-9b7e-4f4a-9f8e-3a3a3a3a3a3a
        eventId:
          type: string
          nullable: true
          example: evt_8a1c0a16d2b14e9c
        visitorId:
          type: string
          nullable: true
          example: vis_aa11bb22cc33dd44
        timestamp:
          type: string
          format: date-time
          example: '2026-04-15T14:32:11.000Z'
        storyId:
          type: string
          example: 61b1e50223b713000a41ca74
        storyTitle:
          type: string
          nullable: true
          example: Sales Presentation Template
        versionId:
          type: string
          example: 65a1e50223b713000a41ca99
        versionTitle:
          type: string
          nullable: true
          example: ACME Corp - Q2 Pitch
        versionCreatedAt:
          type: string
          nullable: true
          format: date-time
          example: '2026-04-10T09:15:00.000Z'
        prospectName:
          type: string
          nullable: true
          example: Jane Cooper
        prospectEmail:
          type: string
          nullable: true
          format: email
          example: jane.cooper@acme.com
        prospectPosition:
          type: string
          nullable: true
          example: VP Marketing
        eventName:
          type: string
          nullable: true
          description: Specific action (e.g. view_slide_3, click_cta)
          example: view_slide_3
        eventCategory:
          type: string
          nullable: true
          description: Always 'view' or 'click'
          example: view
        deviceType:
          type: string
          nullable: true
          example: desktop
        deviceTypeName:
          type: string
          nullable: true
          example: Mac
        eventUrl:
          type: string
          nullable: true
          format: uri
          example: https://view.storydoc.com/abc123
        locationCity:
          type: string
          nullable: true
          example: New York
        locationLatitude:
          type: number
          nullable: true
          format: float
          example: 40.7128
        locationLongitude:
          type: number
          nullable: true
          format: float
          example: -74.006
      required:
      - timestamp
      - storyId
      - versionId
    AnalyticsEventsResponse:
      type: object
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/AnalyticsEventRow"
        pagination:
          type: object
          properties:
            page:
              type: integer
              example: 1
            pageSize:
              type: integer
              example: 1000
            total:
              type: integer
              example: 12453
            totalPages:
              type: integer
              example: 13
            hasMore:
              type: boolean
              example: true
          required:
          - page
          - pageSize
          - total
          - totalPages
          - hasMore
      required:
      - data
      - pagination
      example:
        data:
        - sessionId: 1c2f0c2c-9b7e-4f4a-9f8e-3a3a3a3a3a3a
          eventId: evt_8a1c0a16d2b14e9c
          visitorId: vis_aa11bb22cc33dd44
          timestamp: '2026-04-15T14:32:11.000Z'
          storyId: 61b1e50223b713000a41ca74
          storyTitle: Sales Presentation Template
          versionId: 65a1e50223b713000a41ca99
          versionTitle: ACME Corp - Q2 Pitch
          versionCreatedAt: '2026-04-10T09:15:00.000Z'
          prospectName: Jane Cooper
          prospectEmail: jane.cooper@acme.com
          prospectPosition: VP Marketing
          eventName: view_slide_3
          eventCategory: view
          deviceType: desktop
          deviceTypeName: Mac
          eventUrl: https://view.storydoc.com/abc123
          locationCity: New York
          locationLatitude: 40.7128
          locationLongitude: -74.006
        pagination:
          page: 1
          pageSize: 1000
          total: 12453
          totalPages: 13
          hasMore: true
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Error message
        errorId:
          type: string
          description: Unique error identifier for support
      example:
        error: Error message varies by status code
    Error400:
      type: object
      properties:
        error:
          type: string
          example: Missing data.title in request body.
    Error403:
      type: object
      properties:
        error:
          type: string
          example: Access denied
    Error404:
      type: object
      properties:
        error:
          type: string
          example: Version not found
    Error429:
      type: object
      properties:
        error:
          type: string
          example: Too many requests
    Error500:
      type: object
      properties:
        error:
          type: string
          example: Error occured
        errorId:
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
