The app manifest is a JSON file that defines your app’s configuration, capabilities, and integration points. It serves as the blueprint for how your app interacts with Thena.

Manifest structure

{
  app: AppInfo;
  events: EventDefinitions;
  scopes: ScopeDefinitions;
  metadata: AppMetadata;
  developer: DeveloperInfo;
  activities: Activity[];
  integration: IntegrationConfig;
  configuration: ConfigurationSettings;
}

App information

The app section defines the basic information about your app that users will see in the app directory.

App structure

interface AppInfo {
  name: string;
  icons: {
    large: string;
    small: string;
  };
  category: string;
  description: string;
  supported_locales: string[];
}

App fields

Name

The display name of your app. Keep it concise and descriptive.

{
  "name": "My integration"
}

Icons

URLs to your app’s icons. We recommend:

  • Large: 512x512px PNG
  • Small: 128x128px PNG
{
  "icons": {
    "large": "https://example.com/icon-large.png",
    "small": "https://example.com/icon-small.png"
  }
}

Category

The category that best describes your app’s primary function:

  • productivity
  • communication
  • crm_integration
  • analytics
  • automation
  • custom
{
  "category": "crm_integration"
}

Description

A clear, concise description of what your app does. This appears in the app directory.

{
  "description": "Seamlessly integrate your CRM data with Thena"
}

Supported locales

List of locales your app supports. Use standard locale codes.

{
  "supported_locales": ["en-US", "fr-FR", "de-DE"]
}

Complete app example

{
  "app": {
    "name": "CRM connector",
    "icons": {
      "large": "https://example.com/crm-icon-large.png",
      "small": "https://example.com/crm-icon-small.png"
    },
    "category": "crm_integration",
    "description": "Connect your CRM system to sync contacts, deals, and activities",
    "supported_locales": ["en-US"]
  }
}

Developer info

The developer section contains information about your development team and support resources.

Developer structure

interface DeveloperInfo {
  name: string;
  email: string;
  url: string;
  privacy_policy_url: string;
  terms_of_service_url: string;
  support?: {
    email?: string;
    url?: string;
    documentation_url?: string;
  };
}

Developer fields

Name

Your company or developer name:

{
  "name": "Acme Corporation"
}

Email

Primary contact email for app-related communications:

{
  "email": "apps@acme.com"
}

URL

Your company or app website:

{
  "url": "https://acme.com"
}

Privacy policy URL

Link to your privacy policy:

{
  "privacy_policy_url": "https://acme.com/privacy"
}

Terms of service URL

Link to your terms of service:

{
  "terms_of_service_url": "https://acme.com/terms"
}

Support (optional)

Additional support resources:

{
  "support": {
    "email": "support@acme.com",
    "url": "https://support.acme.com",
    "documentation_url": "https://docs.acme.com"
  }
}

Developer info example

Here’s a full developer info configuration:

{
  "developer": {
    "name": "Acme Corporation",
    "email": "apps@acme.com",
    "url": "https://acme.com",
    "privacy_policy_url": "https://acme.com/privacy",
    "terms_of_service_url": "https://acme.com/terms",
    "support": {
      "email": "support@acme.com",
      "url": "https://support.acme.com",
      "documentation_url": "https://docs.acme.com"
    }
  }
}

Events

The events section defines how your app interacts with Thena’s event system. You can both publish events to notify Thena of changes and subscribe to events to react to changes in Thena.

Events structure

interface EventDefinitions {
  publish: PublishEvent[];
  subscribe: SubscribeEvent[];
}

interface PublishEvent {
  event: string;
  reason: string;
  schema: JSONSchema;
}

interface SubscribeEvent {
  event: string;
  reason: string;
  description: string;
}

Publishing events

Use the publish array to define events your app will emit to Thena.

Publish fields

  • event: The event name (use dot notation)
  • reason: Short description of why this event is published
  • schema: JSON Schema defining the event payload

Publish example

{
  "publish": [
    {
      "event": "contact.synced",
      "reason": "Notify when contact sync is complete",
      "schema": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "description": "The contact ID"
          },
          "sync_status": {
            "type": "string",
            "enum": ["success", "failed"],
            "description": "The sync status"
          }
        },
        "required": ["contact_id", "sync_status"]
      }
    }
  ]
}

Subscribing to events

Use the subscribe array to define which Thena events your app wants to receive.

Subscribe fields

  • event: The event name to subscribe to
  • reason: Short description of why you need this event
  • description: Detailed description of how you’ll use this event

Subscribe example

{
  "subscribe": [
    {
      "event": "contact.created",
      "reason": "Sync new contacts to external system",
      "description": "When a contact is created in Thena, we sync it to our CRM"
    },
    {
      "event": "contact.updated",
      "reason": "Keep contact data in sync",
      "description": "When a contact is updated in Thena, we update our CRM"
    }
  ]
}

Common platform events

App installation event

When your app is installed, you’ll receive an installation event with these details:

{
  "event_type": "app:installation",
  "application_id": "APP123456789",
  "application_name": "Sample App",
  "application_metadata": {
    "title": "Sample Integration",
    "category": "productivity",
    "capabilities": [
      "Data Management",
      "Workflow Automation"
    ],
    "pricing": {
      "monthly": 999,
      "yearly": 9990
    },
    "rating": 4.5
  },
  "bot_id": "BOT123456",
  "bot_token": "pk_live_sample.token123456",
  "organization_id": "ORG123456",
  "team_ids": ["TEAM123456"],
  "created_at": "2024-01-01T12:00:00.000Z",
  "created_by": "USER123456"
}

Ticket comment event

When a ticket comment is added, you’ll receive an event with these details:

{
  "message": {
    "actor": {
      "id": "USER123456",
      "email": "user@example.com",
      "type": "ORG_ADMIN"
    },
    "eventType": "ticket:comment:added",
    "orgId": "ORG123456",
    "payload": {
      "comment": {
        "id": "COMMENT123456",
        "content": "This is a sample comment",
        "contentHtml": "<p>This is a sample comment</p>",
        "contentMarkdown": "This is a sample comment",
        "commentType": "comment",
        "commentVisibility": "public",
        "author": {
          "id": "USER123456",
          "name": "Sample User",
          "email": "user@example.com",
          "avatarUrl": "https://example.com/avatar.jpg"
        },
        "teamId": "TEAM123456",
        "createdAt": "2024-01-01T12:00:00.000Z",
        "updatedAt": "2024-01-01T12:00:00.000Z"
      },
      "ticket": {
        "id": "TICKET123456",
        "title": "Sample support request"
      }
    },
    "eventId": "EVENT123456",
    "timestamp": "1704110400000"
  },
  "xWebhookEvent": true
}

Scopes

The scopes section defines the permissions your app needs to function. Each scope grants access to specific Thena APIs and features.

Scopes structure

interface AppScopes {
  required: string[];
  optional?: string[];
}

Available scopes

Contact scopes

  • contacts:read - View contact information
  • contacts:write - Create and update contacts
  • contacts:delete - Delete contacts
  • contacts.custom_fields:read - View contact custom fields
  • contacts.custom_fields:write - Create and update contact custom fields

Accounts scopes

  • companies:read - View company information
  • companies:write - Create and update companies
  • companies:delete - Delete companies
  • companies.custom_fields:read - View company custom fields
  • companies.custom_fields:write - Create and update company custom fields

Conversation scopes

  • conversations:read - View conversations
  • conversations:write - Send and reply to messages
  • conversations:delete - Delete conversations
  • conversations.attachments:read - View conversation attachments
  • conversations.attachments:write - Add attachments to conversations

User scopes

  • users:read - View user information
  • users.preferences:read - View user preferences
  • users.preferences:write - Update user preferences

Organization scopes

  • workspace:read - View workspace settings
  • workspace.members:read - View workspace members
  • workspace.teams:read - View workspace teams

Scopes example

{
  "scopes": {
    "required": [
      "contacts:read",
      "contacts:write",
      "companies:read",
      "deals:read"
    ],
    "optional": [
      "contacts.custom_fields:write",
      "companies.custom_fields:write",
      "analytics:read",
      "analytics.reports:read"
    ]
  }
}

Metadata

The metadata section provides additional information about your app that helps users understand its capabilities and pricing.

Metadata structure

interface AppMetadata {
  title: string;
  rating?: number;
  pricing?: {
    yearly?: number;
    monthly?: number;
  };
  category: string;
  capabilities: string[];
}

Metadata fields

Title

A concise title that describes your app’s main function:

{
  "title": "CRM & Marketing Integration"
}

Rating

Optional rating for your app (0-5):

{
  "rating": 4.8
}

Pricing

Define your app’s pricing structure (in cents):

{
  "pricing": {
    "yearly": 4990,  // $49.90/year
    "monthly": 499   // $4.99/month
  }
}

Category

The primary category for your app:

{
  "category": "crm_integration"
}

Available categories:

  • crm_integration
  • productivity
  • communication
  • analytics
  • automation
  • custom

Capabilities

List of key features your app provides:

{
  "capabilities": [
    "Contact Management",
    "Company Sync",
    "Deal Pipeline",
    "Ticket Management",
    "Email Integration",
    "Marketing Automation"
  ]
}

Integration

The integration section defines how your app integrates with Thena, including webhook endpoints and entry points.

Integration structure

interface IntegrationConfig {
  webhooks: {
    events: string;
    installations: string;
  };
  entry_points: {
    main: string;
    configuration?: string;
    oauth_redirect?: string;
  };
  interactivity?: {
    request_url?: string;
    message_menu_option_url?: string;
  };
}

Webhooks

Configure endpoints where Thena will send events and installation notifications:

{
  "webhooks": {
    "events": "https://your-app.com/webhook/events",
    "installations": "https://your-app.com/webhook/installation"
  }
}

Events webhook

The events webhook receives all events your app subscribes to:

{
  "event": "contact.created",
  "payload": {
    "id": "contact-123",
    "data": {
      "email": "user@example.com",
      "name": "John Doe"
    }
  }
}

Installation webhook

The installations webhook receives notifications when your app is installed or uninstalled:

{
  "event": "app.installed",
  "payload": {
    "installation_id": "inst-123",
    "bot_token": "bot-token-xyz",
    "workspace_id": "workspace-123"
  }
}

Entry points

Define URLs for different parts of your app’s interface:

{
  "entry_points": {
    "main": "https://your-app.com/app",
    "configuration": "https://your-app.com/config",
    "oauth_redirect": "https://your-app.com/oauth/callback"
  }
}

External select configuration

External select configuration allows you to dynamically fetch options for select fields from your app’s API endpoint.

External select structure

{
  "configuration": {
    "fields": [
      {
        "type": "external_select",
        "key": "project",
        "label": "Project",
        "description": "Select a project",
        "required": true,
        "endpoint": "/api/projects"
      }
    ]
  }
}

Request format

When a user interacts with an external select field, Thena will make a GET request:

GET {your_app_url}{endpoint}?search={search_term}

Response format

Your endpoint should return:

{
  "options": [
    {
      "value": "proj-123",
      "label": "Project A"
    },
    {
      "value": "proj-456",
      "label": "Project B"
    }
  ]
}

Activities

Activities define HTTP-based operations your app can perform. Each activity represents an API endpoint that can be called by Thena.

Activity structure

interface Activity {
  name: string;
  description: string;
  http_config: {
    headers: Record<string, string>;
    httpVerb: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
    endpoint_url: string;
  };
  request_schema: JSONSchema;
  response_schema?: JSONSchema;
}

Activity example

{
  "activities": [
    {
      "name": "create_record",
      "description": "Creates a new record",
      "http_config": {
        "headers": {
          "Content-Type": "application/json"
        },
        "httpVerb": "POST",
        "endpoint_url": "https://api.example.com/records"
      },
      "request_schema": {
        "type": "object",
        "properties": {
          "name": { 
            "type": "string",
            "description": "Name of the record"
          },
          "type": {
            "type": "string",
            "enum": ["contact", "company", "deal"],
            "description": "Type of record to create"
          }
        },
        "required": ["name", "type"]
      },
      "response_schema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID of the created record"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          }
        }
      }
    }
  ]
}

Configuration

Define settings users can configure:

{
  "configuration": {
    "required_settings": [
      {
        "key": "api_key",
        "type": "secret",
        "label": "API Key",
        "required": true,
        "description": "Your API key"
      }
    ],
    "optional_settings": [
      {
        "key": "sync_interval",
        "type": "singleselect",
        "label": "Sync Interval",
        "options": [
          {
            "label": "Every 5 minutes",
            "value": "5min"
          }
        ]
      }
    ]
  }
}

Best practices

App information

  1. Name

    • Keep it short and memorable
    • Avoid unnecessary prefixes
    • Use title case
    • Focus on clarity and recognition
  2. Icons

    • Use high-quality, recognizable images
    • Ensure good contrast
    • Test both sizes in the app directory
    • Maintain consistent branding
  3. Description

    • Focus on value proposition
    • Keep it under 160 characters
    • Use active voice
    • Highlight key features
  4. Category

    • Choose the most specific category
    • Consider user search behavior
    • Use only one primary category
    • Match user expectations

Events

  1. Event naming

    • Use lowercase letters
    • Use dots for namespacing
    • Be specific but concise
    • Follow the pattern: object.action
  2. Schema design

    • Include all necessary fields
    • Add field descriptions
    • Mark required fields
    • Use appropriate types
  3. Event handling

    • Handle events idempotently
    • Implement error handling
    • Log event processing
    • Consider retry logic

Scopes

  1. Scope selection

    • Request minimum required permissions
    • Make enhanced features optional
    • Group related permissions
    • Document scope usage clearly
  2. Security

    • Follow principle of least privilege
    • Regularly audit scope usage
    • Remove unused permissions
    • Update scopes with features
  3. Documentation

    • List all required scopes
    • Explain optional features
    • Document scope dependencies
    • Keep scope list updated

Metadata

  1. Title

    • Keep it clear and concise
    • Focus on main functionality
    • Use proper capitalization
    • Avoid unnecessary words
  2. Pricing

    • Use cents to avoid floating-point issues
    • Offer both monthly and yearly options
    • Consider volume discounts
    • Be transparent about limitations
  3. Capabilities

    • List most important features first
    • Use consistent terminology
    • Keep descriptions short
    • Focus on value proposition

Integration

  1. Webhooks

    • Use HTTPS endpoints
    • Implement proper authentication
    • Handle retries gracefully
    • Respond quickly (under 3 seconds)
  2. Entry points

    • Use consistent URL structure
    • Handle loading states
    • Implement error pages
    • Support deep linking
  3. Security

    • Validate webhook signatures
    • Use HTTPS everywhere
    • Implement rate limiting
    • Monitor for abuse

External select

  1. Performance

    • Cache frequently requested options
    • Limit the number of options returned (max: 100)
    • Implement pagination if needed
    • Optimize response time (under 500ms)
  2. Security

    • Validate the API key
    • Use HTTPS endpoints only
    • Implement rate limiting
    • Return only authorized data
  3. User experience

    • Return results quickly
    • Handle errors gracefully
    • Provide meaningful labels
    • Support search functionality

Activities

  1. Design

    • Use clear, descriptive names
    • Document all parameters
    • Provide complete schemas
    • Include response examples
  2. Implementation

    • Handle errors gracefully
    • Validate input data
    • Set appropriate timeouts
    • Log activity execution
  3. Security

    • Validate authentication
    • Sanitize inputs
    • Rate limit requests
    • Monitor usage patterns

Developer info

  1. Contact information

    • Use business email addresses
    • Monitor support channels regularly
    • Keep contact info up to date
    • Respond promptly to inquiries
  2. Documentation

    • Provide clear installation guides
    • Include troubleshooting steps
    • Document all features
    • Keep docs current with updates
  3. Legal requirements

    • Keep privacy policy current
    • Update terms of service
    • Follow data protection laws
    • Document data usage clearly
  4. Support resources

    • Offer multiple support channels
    • Set clear response times
    • Document known issues
    • Provide self-help resources

Configuration

  1. Settings design

    • Use clear, descriptive labels
    • Group related settings
    • Provide helpful descriptions
    • Use appropriate field types
  2. Validation

    • Validate input formats
    • Provide clear error messages
    • Handle edge cases
    • Implement type checking
  3. Security

    • Encrypt sensitive data
    • Mask secret fields
    • Implement access controls
    • Audit configuration changes