Integration Hub Spoke Generation

SkillDev tools

Generate Integration Hub spokes for connecting external services including spoke actions, connection aliases, data transformations, error handling, and REST/SOAP integrations

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Integration Hub Spoke Generation skill

What this skill tells your AI

The instructions your AI receives, as published by happy-technologies-llc/happy-platform-skills in skills/genai/spoke-generation/SKILL.md and read by ahel’s review.

Overview

This skill covers generating ServiceNow Integration Hub spokes for connecting to external services:

  • Creating spoke containers to organize related integration actions
  • Building spoke actions with REST, SOAP, and scripted steps
  • Configuring connection aliases for secure credential management
  • Defining action inputs and outputs with proper data typing
  • Implementing data transformations between ServiceNow and external formats
  • Adding error handling and retry logic for resilient integrations
  • Packaging spokes for deployment across instances

When to use: When building reusable integrations with external APIs, creating custom connectors for third-party services, or packaging integration logic into deployable spokes.

Prerequisites

  • Roles: integration_admin, flow_designer, or admin
  • Plugins: com.glide.hub.flow_designer (Flow Designer), com.glide.hub.integration (Integration Hub)
  • Access: sys_spoke, sys_hub_action_type_definition, sys_connection_alias tables
  • Knowledge: REST/SOAP API fundamentals, JSON/XML data formats, OAuth and basic authentication
  • Related Skills: genai/flow-generation for consuming spokes in flows

Procedure

Step 1: Analyze the Integration Requirements

Parse the integration request to identify:

  • External service: What system or API to connect to (Slack, Jira, Salesforce, custom REST)
  • Operations: What actions the spoke should support (create, read, update, delete, query)
  • Authentication: How to authenticate (OAuth 2.0, Basic Auth, API Key, mutual TLS)
  • Data format: Request/response format (JSON, XML, form-encoded)
  • Error handling: Expected error codes and retry behavior

Step 2: Query Existing Spokes for Patterns

MCP Approach:

Use SN-Query-Table on sys_spoke:
  - query: active=true
  - fields: sys_id,name,description,scope,logo,active
  - limit: 20

Query existing spoke actions:

Use SN-Query-Table on sys_hub_action_type_definition:
  - query: spoke=<spoke_sys_id>^active=true
  - fields: sys_id,name,description,action_type,inputs,outputs
  - limit: 20

REST Approach:

GET /api/now/table/sys_spoke
  ?sysparm_query=active=true
  &sysparm_fields=sys_id,name,description,scope,active
  &sysparm_limit=20

Step 3: Create the Spoke Record

MCP Approach:

Use SN-Create-Record on sys_spoke:
  - name: "Acme CRM Spoke"
  - description: "Integration spoke for Acme CRM REST API - supports contacts, deals, and activities"
  - scope: "x_acme_crm"
  - logo: ""
  - active: true
  - version: "1.0.0"

REST Approach:

POST /api/now/table/sys_spoke
Body: {
  "name": "Acme CRM Spoke",
  "description": "Integration spoke for Acme CRM REST API - supports contacts, deals, and activities",
  "scope": "x_acme_crm",
  "active": true,
  "version": "1.0.0"
}

Step 4: Create Connection Alias

Connection aliases provide secure, reusable credential storage.

Connection Alias Types:

TypeValueUse Case
HTTP Connectionhttp_connectionREST/SOAP API credentials
JDBC Connectionjdbc_connectionDatabase connections
LDAP Connectionldap_connectionDirectory services
CustomcustomNon-standard authentication

MCP Approach:

Use SN-Create-Record on sys_connection_alias:
  - name: "Acme CRM API"
  - connection_type: "http_connection"
  - description: "Connection alias for Acme CRM REST API"
  - active: true
  - scope: "x_acme_crm"
  - spoke: "<spoke_sys_id>"

REST Approach:

POST /api/now/table/sys_connection_alias
Body: {
  "name": "Acme CRM API",
  "connection_type": "http_connection",
  "description": "Connection alias for Acme CRM REST API",
  "active": true,
  "scope": "x_acme_crm",
  "spoke": "<spoke_sys_id>"
}

Configure Credential (Basic Auth):

Use SN-Create-Record on sys_alias_credential:
  - connection_alias: "<connection_alias_sys_id>"
  - type: "basic_auth"
  - user_name: "${connection.username}"
  - password: "${connection.password}"
  - active: true

Configure Credential (OAuth 2.0):

Use SN-Create-Record on sys_alias_credential:
  - connection_alias: "<connection_alias_sys_id>"
  - type: "oauth2"
  - oauth_profile: "<oauth_profile_sys_id>"
  - active: true

Step 5: Create Spoke Actions

Each action represents an operation the spoke can perform.

MCP Approach:

Use SN-Create-Record on sys_hub_action_type_definition:
  - name: "Create Contact"
  - description: "Creates a new contact in Acme CRM"
  - spoke: "<spoke_sys_id>"
  - action_type: "custom"
  - category: "x_acme_crm"
  - access: "public"
  - active: true
  - annotation: "Creates a contact record in external CRM system"
Use SN-Create-Record on sys_hub_action_type_definition:
  - name: "Get Contact"
  - description: "Retrieves a contact by ID from Acme CRM"
  - spoke: "<spoke_sys_id>"
  - action_type: "custom"
  - category: "x_acme_crm"
  - access: "public"
  - active: true
Use SN-Create-Record on sys_hub_action_type_definition:
  - name: "Search Contacts"
  - description: "Searches contacts in Acme CRM by criteria"
  - spoke: "<spoke_sys_id>"
  - action_type: "custom"
  - category: "x_acme_crm"
  - access: "public"
  - active: true

REST Approach:

POST /api/now/table/sys_hub_action_type_definition
Body: {
  "name": "Create Contact",
  "description": "Creates a new contact in Acme CRM",
  "spoke": "<spoke_sys_id>",
  "action_type": "custom",
  "category": "x_acme_crm",
  "access": "public",
  "active": true
}

Step 6: Define Action Inputs

MCP Approach:

Use SN-Create-Record on sys_hub_action_input:
  - action_type: "<create_contact_action_sys_id>"
  - name: "first_name"
  - label: "First Name"
  - type: "string"
  - mandatory: true
  - order: 100
Use SN-Create-Record on sys_hub_action_input:
  - action_type: "<create_contact_action_sys_id>"
  - name: "last_name"
  - label: "Last Name"
  - type: "string"
  - mandatory: true
  - order: 200
Use SN-Create-Record on sys_hub_action_input:
  - action_type: "<create_contact_action_sys_id>"
  - name: "email"
  - label: "Email Address"
  - type: "string"
  - mandatory: true
  - order: 300
Use SN-Create-Record on sys_hub_action_input:
  - action_type: "<create_contact_action_sys_id>"
  - name: "company_id"
  - label: "Company ID"
  - type: "string"
  - mandatory: false
  - order: 400

REST Approach:

POST /api/now/table/sys_hub_action_input
Body: {
  "action_type": "<create_contact_action_sys_id>",
  "name": "email",
  "label": "Email Address",
  "type": "string",
  "mandatory": true,
  "order": 300
}

Step 7: Add REST Steps to Actions

REST steps define the actual HTTP calls to external services.

MCP Approach:

Use SN-Create-Record on sys_hub_rest_step:
  - action_type: "<create_contact_action_sys_id>"
  - name: "Call Create Contact API"
  - order: 100
  - connection_alias: "<connection_alias_sys_id>"
  - http_method: "POST"
  - resource_path: "/api/v2/contacts"
  - content_type: "application/json"
  - request_body: '{
      "first_name": "${inputs.first_name}",
      "last_name": "${inputs.last_name}",
      "email": "${inputs.email}",
      "company_id": "${inputs.company_id}"
    }'
  - headers: '[{"name":"Accept","value":"application/json"}]'

REST Approach:

POST /api/now/table/sys_hub_rest_step
Body: {
  "action_type": "<create_contact_action_sys_id>",
  "name": "Call Create Contact API",
  "order": 100,
  "connection_alias": "<connection_alias_sys_id>",
  "http_method": "POST",
  "resource_path": "/api/v2/contacts",
  "content_type": "application/json",
  "request_body": "{\"first_name\":\"${inputs.first_name}\",\"last_name\":\"${inputs.last_name}\",\"email\":\"${inputs.email}\"}"
}

GET Request Example:

Use SN-Create-Record on sys_hub_rest_step:
  - action_type: "<get_contact_action_sys_id>"
  - name: "Call Get Contact API"
  - order: 100
  - connection_alias: "<connection_alias_sys_id>"
  - http_method: "GET"
  - resource_path: "/api/v2/contacts/${inputs.contact_id}"
  - content_type: "application/json"
  - headers: '[{"name":"Accept","value":"application/json"}]'

Step 8: Define Action Outputs

MCP Approach:

Use SN-Create-Record on sys_hub_action_output:
  - action_type: "<create_contact_action_sys_id>"
  - name: "contact_id"
  - label: "Contact ID"
  - type: "string"
  - order: 100
Use SN-Create-Record on sys_hub_action_output:
  - action_type: "<create_contact_action_sys_id>"
  - name: "status_code"
  - label: "HTTP Status Code"
  - type: "integer"
  - order: 200
Use SN-Create-Record on sys_hub_action_output:
  - action_type: "<create_contact_action_sys_id>"
  - name: "response_body"
  - label: "Response Body"
  - type: "string"
  - order: 300

Step 9: Add Error Handling with Script Steps

MCP Approach:

Use SN-Create-Record on sys_hub_script_step:
  - action_type: "<create_contact_action_sys_id>"
  - name: "Handle Response"
  - order: 200
  - script: |
      (function execute(inputs, outputs) {
        var statusCode = inputs.rest_step_status_code;
        var responseBody = inputs.rest_step_response_body;

        if (statusCode == 201) {
          var response = JSON.parse(responseBody);
          outputs.contact_id = response.id;
          outputs.status_code = statusCode;
        } else if (statusCode == 409) {
          throw new Error('Contact already exists: ' + responseBody);
        } else if (statusCode == 429) {
          throw new Error('Rate limit exceeded. Retry after cooldown.');
        } else {
          throw new Error('API error ' + statusCode + ': ' + responseBody);
        }
      })(inputs, outputs);

Step 10: Test and Publish the Spoke

MCP Approach:

Use SN-Update-Record on sys_spoke:
  - sys_id: "<spoke_sys_id>"
  - active: true

Verify all actions are properly configured:

Use SN-Query-Table on sys_hub_action_type_definition:
  - query: spoke=<spoke_sys_id>
  - fields: sys_id,name,active,action_type
  - limit: 50

Verify connection alias is available:

Use SN-Query-Table on sys_connection_alias:
  - query: spoke=<spoke_sys_id>
  - fields: sys_id,name,connection_type,active

Tool Usage

ToolPurposeWhen to Use
SN-Query-TableFind existing spokes and actionsPattern discovery and validation
SN-Create-RecordCreate spokes, actions, inputs, outputs, stepsBuilding spoke components
SN-Update-RecordModify spoke settings, activate spokesEditing and publishing
SN-Get-Table-SchemaDiscover spoke table fieldsUnderstanding available configurations

Best Practices

  1. One spoke per external service -- avoid mixing multiple APIs in a single spoke
  2. Use connection aliases for all credentials -- never hardcode secrets in scripts or REST steps
  3. Define comprehensive inputs/outputs with clear labels and proper data types
  4. Always add error handling -- parse HTTP status codes and provide meaningful error messages
  5. Implement retry logic for transient failures (429, 503) using script steps
  6. Use pagination for search/list actions to handle large result sets
  7. Version your API paths in resource_path to support API evolution
  8. Log integration calls for debugging with appropriate verbosity levels
  9. Test with mock data before connecting to production external services
  10. Document rate limits and throttling behavior in the spoke description

Troubleshooting

IssueCauseResolution
Connection test failsInvalid credentials or URL in connection aliasVerify connection alias configuration and test connectivity
401 UnauthorizedOAuth token expired or invalid credentialsRefresh OAuth token or update credential record
403 ForbiddenAPI key lacks required permissionsCheck external service permissions for the integration user
REST step timeoutExternal service slow or unreachableIncrease timeout on REST step or check network connectivity
Response parsing errorUnexpected response format from APIAdd defensive JSON parsing in script step with try/catch
Action not visible in Flow DesignerAction access set to private or spoke inactiveSet access to "public" and verify spoke is active
Input data truncatedString field length limitsUse multi-line text type for large payloads

Examples

Example 1: Slack Notification Spoke

Generate a spoke for sending Slack messages:

  • Action 1: Send Message -- POST to /api/chat.postMessage with channel, text, attachments
  • Action 2: Create Channel -- POST to /api/conversations.create with name, is_private
  • Action 3: Upload File -- POST to /api/files.upload with channels, file content
  • Connection: OAuth 2.0 with Slack Bot Token
  • Error Handling: Handle rate limits (429), channel not found (channel_not_found)

Example 2: Jira Integration Spoke

Generate a spoke for Jira Cloud operations:

  • Action 1: Create Issue -- POST to /rest/api/3/issue with project, summary, description, issuetype
  • Action 2: Get Issue -- GET /rest/api/3/issue/{issueKey} returning status, assignee, priority
  • Action 3: Add Comment -- POST to /rest/api/3/issue/{issueKey}/comment with body
  • Action 4: Transition Issue -- POST to /rest/api/3/issue/{issueKey}/transitions
  • Connection: Basic Auth with API token, base URL configurable per instance

Example 3: Custom REST API Spoke

Generate a spoke for a custom internal microservice:

  • Action 1: Submit Order -- POST /api/v1/orders with line items, customer, shipping address
  • Action 2: Check Order Status -- GET /api/v1/orders/{orderId} returning status, tracking number
  • Action 3: Cancel Order -- DELETE /api/v1/orders/{orderId} with reason
  • Connection: API Key authentication via custom header
  • Data Transform: Map ServiceNow catalog variables to API request format

Related Skills

  • genai/flow-generation - Flow Designer flows that consume spoke actions
  • genai/playbook-generation - Playbooks that call spoke actions as activities
  • catalog/approval-workflows - Approval flows that may trigger external notifications
  • admin/instance-management - Connection alias and credential configuration

Signals

GitHub stars
37
Forks
13
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
spoke-generation
Source
github.com/happy-technologies-llc/happy-platform-skills