Skip to main content
The External Actor Gateway (EAG) provides a RESTful API for external systems to integrate with the Architect platform. This API enables third-party applications to programmatically manage brands, page groups, templates, and analytics.

Getting Started

To begin using the API:
  1. Obtain API credentials - Contact your account manager to receive an API key
  2. Authenticate requests - Include your API key in the x-api-key header for all requests
  3. Explore the API reference - Browse the available endpoints in the API Reference tab

Core Concepts

Brands

Brands represent your organization’s visual identity and theme configuration. Each brand includes:
  • Name and company homepage
  • Theme customization (light and dark modes)
  • Color schemes and logo assets
  • Preferred appearance settings

Page Groups

Page groups are collections of related pages with shared configuration:
  • Template assignment
  • Business goals and objectives
  • URL slugs and titles
  • Publication status (draft, published, archived)
  • Custom scripts and tracking

Pages

Individual page variants within a page group, each with:
  • Version history
  • Statistics and analytics
  • UTM parameter tracking
  • Session counts

Templates

Reusable page templates for consistent design:
  • System templates (provided by Architect)
  • Custom templates (created by your team)
  • Template duplication and customization
  • Version control

Authentication

All API requests require authentication using an API key:
curl -X GET 'https://app.tryarchitect.com/api/eag/v0/brands' \
  -H 'x-api-key: YOUR_API_KEY'

Rate Limiting

The API implements rate limiting to ensure fair usage. If you exceed the rate limit, you’ll receive a 429 error response with details about when you can retry.

Error Handling

The API uses standard HTTP status codes and returns detailed error responses:
{
  "code": "VALIDATION_ERROR",
  "message": "Validation failed",
  "requestId": "req_01j5k9m7n8p9q2r3s4t5v6w7x8",
  "details": {
    "field": "name",
    "reason": "Name is required"
  }
}

Webhook Signature Verification

Webhook requests include an HMAC-SHA256 signature in the X-Webhook-Signature-256 header that you should verify to ensure authenticity and prevent tampering.

Verification Process

  1. Extract the signature from the X-Webhook-Signature-256 header (format: sha256=<hex-signature>)
  2. Get the raw request body before parsing
  3. Calculate the expected signature using your webhook signing secret
  4. Compare signatures using a timing-safe comparison function
  5. Process the webhook only if signatures match
Always use the raw request body for verification, not the parsed JSON. Use timing-safe comparison functions to prevent timing attacks.

Implementation Example

import crypto from 'node:crypto';
import express from 'express';

function verifyWebhookSignature(
  signingSecret: string,
  payload: string,
  signature: string
): boolean {
  if (!signingSecret || !payload || !signature?.startsWith('sha256=')) {
    return false;
  }

  try {
    const receivedSignature = signature.substring(7);
    const expectedSignature = crypto
      .createHmac('sha256', signingSecret)
      .update(payload, 'utf8')
      .digest('hex');

    return crypto.timingSafeEqual(
      Buffer.from(expectedSignature, 'hex'),
      Buffer.from(receivedSignature, 'hex')
    );
  } catch (error) {
    console.error('Signature verification failed:', error);
    return false;
  }
}

Security Best Practices

  • Store signing secrets in environment variables, never hardcode them
  • Always verify signatures before processing webhook data
  • Use timing-safe comparison functions (crypto.timingSafeEqual() in Node.js, hmac.compare_digest() in Python)
  • Only accept webhooks over HTTPS
  • Log verification failures for security monitoring
  • Implement rate limiting on webhook endpoints

Troubleshooting

Cause: Using parsed JSON instead of raw request bodySolution: Use the raw request body string before any parsing:
  • Express: express.raw({ type: 'application/json' }) and req.body.toString()
  • Flask: request.get_data(as_text=True)
  • FastAPI: await request.body() then .decode('utf-8')
Cause: Missing header or incorrect formatSolution: Verify the X-Webhook-Signature-256 header is present and starts with sha256=. Check for header case sensitivity in your framework.
Cause: Inconsistent encoding when converting body to stringSolution: Ensure consistent UTF-8 encoding throughout your verification process.

Support

For API support or questions:

API Environments

The API is available in multiple environments:
  • Production: https://app.tryarchitect.com/api/eag
  • Beta: https://app.beta.tryarchitect.com/api/eag
  • Local Development: http://localhost:25001