Skip to main content
When you build a custom connector, you can embed step-by-step setup guides directly in the connector YAML configuration. These guides are exposed through the StackOne API’s /actions endpoint and can be rendered in your own documentation, dashboards, or integration hubs.

Overview

Connector documentation consists of two types of guides:

Account Link Guides

For end-users - Instructions to connect their account via Integration Hub. Covers finding credentials like API keys, domains, and OAuth authorization.

Auth Setup Guides

For application setup - Instructions to register OAuth applications and obtain client credentials before users can connect.
Where guides go:
  • Account link guides → authentication[].{method}.support.guides.config
  • Auth setup guides → authentication[].{method}.support.guides.setup

Guide Structure in YAML

Guides are added to the authentication block in your connector YAML configuration.

Basic Example

authentication:
  - custom:
      type: custom
      label: API Key
      support:
        guides:
          config:                          # Account linking guide (for end-users/resource owners)
            warning: "Admin access required to generate an API key."
            sections:
              - title: Generating an API Key
                content: |
                  Instructions for finding the API key.
                steps:
                  - title: Navigate to Settings
                    content: |
                      Go to Settings > API in your account.
                  - title: Create Key
                    content: |
                      Click Generate API Key and copy it.
      authorization:
        type: bearer
        token: $.credentials.apiKey
      configFields:
        - key: apiKey
          label: API Key
          type: password
          required: true
          secret: true

When to Use Each Guide Type

Guide TypeField DependencyPurposeAudience
guides.configRequires configFieldsHow end-users get their credentialsEnd-users (resource owners)
guides.setupRequires setupFieldsHow to register OAuth apps and obtain client credentialsApplication owners
Only include guides.config if configFields exists. Only include guides.setup if setupFields exists.
Critical: Set support.link to the URL where you’ll render these guides in your own documentation or dashboard. The Integration Hub uses this link to direct users to your rendered guides. If not set, the Hub will link to StackOne’s generic documentation instead of your custom instructions.
authentication:
  - custom:
      type: custom
      label: API Key
      support:
        link: https://docs.yourcompany.com/integrations/provider-setup  # Required
        description: Admin privileges required
        guides:
          config:
            # ... your guide content
The support.link should point to where you host the rendered version of these guides, ensuring users see your branded, customized setup instructions.

Section Structure

Each guide contains an array of sections with steps.

Section Properties

sections:
  - title: Section Title                   # Required
    content: |                             # Optional - Intro text
      Section overview text.
    list:                                  # Optional - Bullet points
      - Item 1
      - Item 2
    steps:                                 # Optional - Nested steps
      - title: Step Title
        content: |
          Step instructions.
        list:
          - Sub-item 1
          - Sub-item 2
    applicableScopes: employees:read       # Optional - Filter by scopes (space-separated)

Content Formatting

The content and list fields contain plain strings. To render markdown formatting, use a markdown parser in your rendering code. Common patterns include:
  • Links: [Provider Dashboard](https://example.com/dashboard) → Parse with markdown renderer to create clickable links
  • Bold: **Settings** for UI elements → Parse to render as <strong>Settings</strong>
  • Code: `https://api.example.com` → Parse to render as <code>https://api.example.com</code>
The API returns raw strings with markdown syntax. You’re responsible for parsing and rendering them. Use libraries like react-markdown, marked, or similar, and always sanitize HTML output with tools like DOMPurify to prevent XSS attacks.

Scope Definitions

Preview Feature: Scope definitions and scope-aware guides are under active development. The structure and behavior may change. Currently used primarily for OAuth scopes, but designed to support any action requirements (pricing tiers, platform configuration, feature flags, etc.).
Define action requirements in scopeDefinitions at the connector root level. While commonly used for OAuth/API scopes, these can represent any prerequisite needed to enable an action.

Basic Scopes

scopeDefinitions:
  employees:read:
    description: Read employee data
  employees:write:
    description: Create and update employee records
    includes: employees:read              # Write includes read
Scopes aren’t limited to API permissions. Use them to represent pricing tiers (plan:enterprise), platform features (feature:advanced_reporting), or configuration requirements (config:sso_enabled).

Hierarchical Scopes

scopeDefinitions:
  https://www.googleapis.com/auth/drive:
    description: View and manage all Drive files
    includes: https://www.googleapis.com/auth/drive.readonly
  https://www.googleapis.com/auth/drive.readonly:
    description: View all Drive files (read-only)
Rules:
  • Write scopes typically include read scopes via includes
  • Broader scopes include narrower scopes
  • Only include relationships explicitly documented by provider
  • Read-only scopes should NOT include write scopes

Scope-Aware Guide Content

Guide sections can be filtered based on selected scopes or requirements, showing only relevant instructions for the user’s configuration.

Basic Scope Filtering

guides:
  config:
    sections:
      - title: Read Permissions
        applicableScopes: employees:read   # Only show this section when this scope selected
        steps:
          - title: Enable Read Access
            content: |
              Grant read permissions in the admin panel.

      - title: Write Permissions
        applicableScopes: employees:write  # Only show this section when this scope selected
        steps:
          - title: Enable Write Access
            content: |
              Grant write permissions for creating/updating employees.

Displaying Actions Enabled by Requirements

Use displayScopes: true to show which actions a step enables:
steps:
  - title: Select API Scopes
    content: |
      Choose the scopes you need based on your use case.
    displayScopes: true
    applicableScopes: employees:read employees:write departments:read  # Space-separated list
When rendered, this shows badges indicating which actions are enabled by these requirements (scopes, features, etc.).

Complete Examples

API Key Authentication

authentication:
  - custom:
      type: custom
      label: API Key
      support:
        description: Admin privileges required
        guides:
          config:
            warning: "Admin access to your account is required to generate an API key."
            sections:
              - title: Generating an API Key
                content: |
                  Generate an API key from your admin dashboard.
                steps:
                  - title: Sign in and open API settings
                    content: |
                      Sign in to your [Provider account](https://app.provider.com/signin).
                    list:
                      - Click **Settings** in the top navigation
                      - Select **API** from the sidebar
                      - Click **Create API Key**
                  - title: Name and create the key
                    content: |
                      Give your API key a descriptive name.
                    list:
                      - "**Name:** Enter 'StackOne Integration'"
                      - Click **Generate Key**
                  - title: Copy the API key
                    content: |
                      Copy your new API Key and store it securely.
                    list:
                      - This key will only be shown once
                      - Save it in a secure password manager
      authorization:
        type: bearer
        token: $.credentials.apiKey
      configFields:
        - key: apiKey
          label: API Key
          type: password
          required: true
          secret: true
          placeholder: sk_live_abc123def456
          description: Generate via Settings > API in your Provider account
      environments:
        - key: production
          name: Production

OAuth 2.0 with Setup Guide

authentication:
  - oauth2:
      type: oauth2
      label: OAuth 2.0
      support:
        description: OAuth application setup required
        guides:
          setup:                           # For application owners - registering OAuth client
            warning: "Admin access required to create OAuth applications."
            sections:
              - title: Create OAuth Application
                content: |
                  Register an OAuth application in your Provider dashboard.
                steps:
                  - title: Navigate to OAuth Apps
                    content: |
                      Go to Settings > Developer > OAuth Applications.
                  - title: Register New Application
                    content: |
                      Click **New OAuth App** and configure:
                    list:
                      - "**Application Name:** StackOne"
                      - "**Redirect URI:** `https://api.stackone.com/connect/oauth2/provider_key/callback`"
                  - title: Copy Credentials
                    content: |
                      Save your Client ID and Client Secret.
                    list:
                      - Copy the Client ID immediately
                      - Generate and copy the Client Secret
                      - Store both securely for use later
          config:                          # For end-users/resource owners - authorizing access
            sections:
              - title: OAuth Connection Flow
                content: |
                  Authorize StackOne to access your account.
                steps:
                  - title: Initiate Connection
                    content: |
                      Click **Connect** in the StackOne Hub.
                  - title: Review Permissions
                    content: |
                      Review the requested permissions.
                    displayScopes: true
                    applicableScopes: employees:read employees:write  # Space-separated list
                  - title: Authorize Access
                    content: |
                      Click **Authorize** to grant access.
      authorization:
        type: oauth2
        authorizationUrl: https://provider.com/oauth/authorize
        tokenUrl: https://provider.com/oauth/token
        tokenRequest:
        args:
          - name: client_id
            value: $.credentials.clientId
            in: body
          - name: client_secret
            value: $.credentials.clientSecret
            in: body
          - name: code
            value: $.credentials.code
            in: body
          - name: grant_type
            value: authorization_code
            in: body
      setupFields:
        - key: clientId
          label: Client ID
          type: text
          required: true
        - key: clientSecret
          label: Client Secret
          type: password
          required: true
          secret: true

scopeDefinitions:
  employees:read:
    description: Read employee data
  employees:write:
    description: Create and update employee records
    includes: employees:read

Retrieving Guides via API

Once your connector is deployed, guides are available through the /actions API endpoint.

API Request

curl -X GET "https://api.stackone.com/actions?include=authentication_guides&filter[connectors]=your_provider" \
  -H "Authorization: Basic $(echo -n 'YOUR_API_KEY:' | base64)"

Response Structure

{
  "data": [
    {
      "key": "your_provider",
      "name": "Your Provider",
      "icon": "https://stackone-logos.com/api/your_provider/filled/png",
      "authentication": [
        {
          "type": "custom",
          "label": "API Key",
          "key": "api_key",
          "configFields": [
            {
              "key": "apiKey",
              "label": "API Key",
              "type": "password",
              "required": true,
              "secret": true,
              "placeholder": "sk_live_abc123"
            }
          ],
          "support": {
            "guides": {
              "config": {
                "warning": "Admin access required to generate an API key.",
                "sections": [
                  {
                    "title": "Generating an API Key",
                    "content": "Generate an API key from your admin dashboard.",
                    "steps": [
                      {
                        "title": "Sign in and open API settings",
                        "content": "Sign in to your Provider account.",
                        "list": [
                          "Click **Settings** in the top navigation",
                          "Select **API** from the sidebar",
                          "Click **Create API Key**"
                        ]
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      ],
      "actions": [
        {
          "id": "your_provider_list_employees",
          "label": "List Employees",
          "required_scopes": ["employees:read"]
        }
      ]
    }
  ],
  "next": null
}

Query Parameters

ParameterDescriptionExample
includeMust include authentication_guidesinclude=authentication_guides
filter[connectors]Filter by connector keyfilter[connectors]=bamboohr
page_sizeResults per pagepage_size=100
nextPagination cursornext=cursor_string

Rendering Guides in Your System

You can render the guides however you choose. Here’s a basic approach using TypeScript and React:

1. Fetch and Parse

interface GuideSection {
  title: string;  // Required per YAML schema
  content?: string;
  list?: string[];
  steps?: GuideStep[];
  applicableScopes?: string[];
}

interface GuideStep {
  title: string;  // Required per YAML schema
  content?: string;
  list?: string[];
  displayScopes?: boolean;  // Whether to show requirement badges for this step
  applicableScopes?: string[];  // Filter step by requirements (OAuth scopes, features, etc.)
}

interface AuthGuides {
  config?: {
    warning?: string;
    sections?: GuideSection[];
  };
  setup?: {
    warning?: string;
    sections?: GuideSection[];
  };
}

async function fetchConnectorGuides(
  connectorKey: string,
  apiKey: string,
  authMethodKey?: string
): Promise<AuthGuides> {
  // Browser: btoa(apiKey + ':')
  // Node.js: Buffer.from(apiKey + ':').toString('base64')
  const authHeader = typeof btoa !== 'undefined'
    ? btoa(apiKey + ':')
    : Buffer.from(apiKey + ':').toString('base64');

  const response = await fetch(
    `https://api.stackone.com/actions?include=authentication_guides&filter[connectors]=${connectorKey}`,
    {
      headers: {
        'Authorization': `Basic ${authHeader}`
      }
    }
  );

  const data = await response.json();

  // Normalize connectors list from API response (supports both documented and legacy shapes)
  const connectors = Array.isArray(data?.data)
    ? data.data
    : Array.isArray(data?.results)
    ? data.results
    : [];

  // Find the connector by key
  const connector = connectors.find(
    (c: any) => c.key === connectorKey || c.connector_key === connectorKey
  );

  if (!connector) {
    throw new Error(`Connector "${connectorKey}" not found`);
  }

  // Find the auth method by key, or use the first one
  const auth = authMethodKey
    ? connector.authentication?.find((a: any) => a.key === authMethodKey)
    : connector.authentication?.[0];

  if (!auth) {
    throw new Error(`Auth method not found`);
  }

  return auth.support?.guides || {};
}

2. Render Content

Use a proper Markdown parser (like react-markdown or marked) with HTML sanitization (like DOMPurify) instead of regex replacements. The example below is simplified for demonstration and should not be used in production without proper sanitization.
// PRODUCTION: Use react-markdown + DOMPurify for safe rendering
// Example: import ReactMarkdown from 'react-markdown'
// Example: import DOMPurify from 'dompurify'

function renderGuideContent(content: string): string {
  // SIMPLIFIED EXAMPLE - Add HTML sanitization for production use
  const escapeHtml = (text: string) =>
    text.replace(/[&<>"']/g, (m) => ({
      '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;'
    }[m] || m));

  return content
    .replace(/\*\*(.*?)\*\*/g, (_, text) => `<strong>${escapeHtml(text)}</strong>`)
    .replace(/`(.*?)`/g, (_, text) => `<code>${escapeHtml(text)}</code>`)
    .replace(/\[(.*?)\]\((.*?)\)/g, (_, text, url) =>
      `<a href="${escapeHtml(url)}">${escapeHtml(text)}</a>`
    );
}

function renderSection(section: GuideSection): JSX.Element {
  return (
    <div className="guide-section">
      {section.title && <h3>{section.title}</h3>}
      {section.content && (
        <div dangerouslySetInnerHTML={{ __html: renderGuideContent(section.content) }} />
      )}
      {section.list && (
        <ul>
          {section.list.map((item, i) => (
            <li key={i} dangerouslySetInnerHTML={{ __html: renderGuideContent(item) }} />
          ))}
        </ul>
      )}
      {section.steps && section.steps.map((step, i) => (
        <div key={i} className="guide-step">
          {step.title && <h4>{step.title}</h4>}
          {step.content && (
            <div dangerouslySetInnerHTML={{ __html: renderGuideContent(step.content) }} />
          )}
          {step.list && (
            <ul>
              {step.list.map((item, j) => (
                <li key={j} dangerouslySetInnerHTML={{ __html: renderGuideContent(item) }} />
              ))}
            </ul>
          )}
        </div>
      ))}
    </div>
  );
}

3. Handle Requirement Filtering

function filterByRequirements(
  sections: GuideSection[],
  selectedRequirements: string[]
): GuideSection[] {
  return sections.filter(section => {
    if (!section.applicableScopes) return true;
    // Show section if any of its requirements are met
    return section.applicableScopes.some(req => selectedRequirements.includes(req));
  });
}

Validation

After adding guides to your connector YAML, validate the configuration:
stackone validate connectors/your-provider/your-provider.connector.s1.yaml
If you see a warning about Unknown field 'guides', update your CLI to the latest version with npm install -g @stackone/cli@latest. The guides field is fully supported at runtime.

Testing Your Guides

1. Deploy Connector

stackone push connectors/your-provider/ --api-key YOUR_API_KEY

2. Fetch from API

curl -X GET "https://api.stackone.com/actions?include=authentication_guides&filter[connectors]=your_provider" \
  -H "Authorization: Basic $(echo -n 'YOUR_API_KEY:' | base64)"

3. Verify Response

Check that:
  • authentication[].support.guides.config exists if configFields exist
  • authentication[].support.guides.setup exists if setupFields exist
  • All sections have title and content or steps
  • Links are properly formatted
  • Requirement filters (applicableScopes) match your scopeDefinitions if used

Migration from Hub Docs

If you have existing guides in separate documentation, you can migrate them to the connector YAML.

MDX to YAML Mapping

MDX ElementYAML Equivalent
<Warning> at topwarning: field
## Section Title- title: Section Title
<Steps> blocksteps: array
<Step title="...">- title: in steps
Paragraph contentcontent: | (multiline)
Bulleted listlist: array
<Frame><img>Omit (images not in YAML)
Links [text](url)Keep as-is

Example Migration

From MDX:
<Warning>
  Admin privileges required.
</Warning>

## Finding Your API Key

<Steps>
  <Step title="Open Settings">
    Navigate to Settings > API Keys.
    - Click **Generate Key**
    - Copy the key immediately
  </Step>
</Steps>
To YAML:
guides:
  config:
    warning: "Admin privileges required."
    sections:
      - title: Finding Your API Key
        content: |
          Generate your API key from the admin dashboard.
        steps:
          - title: Open Settings
            content: |
              Navigate to Settings > API Keys.
            list:
              - Click **Generate Key**
              - Copy the key immediately

Next Steps

Build Your Connector

Create the connector YAML configuration

Connector Structure

Learn about authentication patterns and actions

YAML Reference

Complete reference for all YAML properties

CLI Reference

Deploy and test connectors with the CLI