Config

The Config API allows you to store and retrieve JSON configuration files at different scopes: organization-wide, repository-wide, or path-specific. Configs support both single-sheet and multi-sheet JSON formats.

Common Use Cases:

Create or Update Config

POST /config/{org}/{repo}/{path}

Creates a new configuration or updates an existing one. Configs must be valid JSON and follow the single-sheet or multi-sheet format.

Parameters

Headers

https://main--docket--da-pilot.aem.live/fragments/api/headers

Path

Body

Content-Type: multipart/form-data

Examples

Multi-Sheet Config

  • curl (bash)
  • Javascript
curl -X POST \
  'https://admin.da.live/config/geometrixx/outdoors/config' \
  --header 'Authorization: Bearer {IMS_TOKEN}' \
  --form 'config={
    ":names": ["permissions", "settings"],
    ":type": "multi-sheet",
    "permissions": {
      "total": 1,
      "data": [
        {
          "path": "CONFIG",
          "actions": "write",
          "groups": "admins"
        }
      ]
    },
    "settings": {
      "total": 2,
      "data": [
        {
          "key": "site-name",
          "value": "Geometrixx Outdoors"
        },
        {
          "key": "theme",
          "value": "adventure"
        }
      ]
    }
  }'
async function createConfig(org, repo, path, configData) {
  const formData = new FormData();
  formData.append('config', JSON.stringify(configData));

  const response = await fetch(
    `https://admin.da.live/config/${org}/${repo}/${path}`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${IMS_TOKEN}`
      },
      body: formData
    }
  );

  if (response.status === 401) {
    throw new Error('Authentication failed');
  }

  if (response.status === 400) {
    const error = await response.json();
    throw new Error(error.error || 'Invalid config');
  }

  if (response.status === 201) {
    return await response.json();
  }

  throw new Error(`Unexpected status: ${response.status}`);
}

// Usage - multi-sheet config
const multiSheetConfig = {
  ":names": ["permissions", "settings"],
  ":type": "multi-sheet",
  "permissions": {
    "total": 1,
    "data": [
      {
        "path": "CONFIG",
        "actions": "write",
        "groups": "admins"
      }
    ]
  },
  "settings": {
    "total": 2,
    "data": [
      {
        "key": "site-name",
        "value": "Geometrixx Outdoors"
      },
      {
        "key": "theme",
        "value": "adventure"
      }
    ]
  }
};

await createConfig('geometrixx', 'outdoors', 'config', multiSheetConfig);

Single-Sheet Config

  • curl (bash)
  • Javascript
curl -X POST \
  'https://admin.da.live/config/geometrixx/outdoors/permissions' \
  --header 'Authorization: Bearer {IMS_TOKEN}' \
  --form 'config={
    ":sheetname": "permissions",
    ":type": "sheet",
    "total": 2,
    "data": [
      {
        "path": "CONFIG",
        "actions": "write",
        "groups": "admins"
      },
      {
        "path": "/drafts",
        "actions": "read,write",
        "groups": "editors"
      }
    ]
  }'
// Usage - single-sheet config
const singleSheetConfig = {
  ":sheetname": "permissions",
  ":type": "sheet",
  "total": 2,
  "data": [
    {
      "path": "CONFIG",
      "actions": "write",
      "groups": "admins"
    },
    {
      "path": "/drafts",
      "actions": "read,write",
      "groups": "editors"
    }
  ]
};

await createConfig('geometrixx', 'outdoors', 'permissions', singleSheetConfig);

Path-Specific Config

  • Javascript
// Create config for a specific path or page
const pageConfig = {
  ":names": ["permissions", "metadata"],
  ":type": "multi-sheet",
  "permissions": {
    "total": 1,
    "data": [
      {
        "path": "CONFIG",
        "actions": "write",
        "groups": "editors"
      }
    ]
  },
  "metadata": {
    "total": 3,
    "data": [
      {
        "property": "title",
        "value": "Product Landing Page"
      },
      {
        "property": "template",
        "value": "landing"
      },
      {
        "property": "seo-description",
        "value": "Discover our latest products"
      }
    ]
  }
};

await createConfig('geometrixx', 'outdoors', 'products/landing-page-config', pageConfig);

Response

  • 201 (json)
{
  ":names": ["permissions", "settings"],
  ":type": "multi-sheet",
  "permissions": {
    "total": 1,
    "data": [
      {
        "path": "CONFIG",
        "actions": "write",
        "groups": "admins"
      }
    ]
  },
  "settings": {
    "total": 2,
    "data": [
      {
        "key": "site-name",
        "value": "Geometrixx Outdoors"
      },
      {
        "key": "theme",
        "value": "adventure"
      }
    ]
  }
}

Behavior Notes:

Permissions Validation:

Error Responses:

Get Config

GET /config/{org}/{repo}/{path}

Retrieves a configuration by path.

Parameters

Headers

https://main--docket--da-pilot.aem.live/fragments/api/headers

Path

Examples

Get Config

  • curl (bash)
  • Javascript
curl -X GET \
  'https://admin.da.live/config/geometrixx/outdoors/config' \
  --header 'Authorization: Bearer {IMS_TOKEN}'
async function getConfig(org, repo, path) {
  const response = await fetch(
    `https://admin.da.live/config/${org}/${repo}/${path}`,
    {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${IMS_TOKEN}`,
        'Accept': 'application/json'
      }
    }
  );

  if (response.status === 401) {
    throw new Error('Authentication failed');
  }

  if (response.status === 404) {
    return null; // Config not found
  }

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }

  return await response.json();
}

// Usage
const config = await getConfig('geometrixx', 'outdoors', 'config');

if (config) {
  // Access multi-sheet config
  const siteName = config.settings.data.find(s => s.key === 'site-name')?.value;
  console.log(`Site: ${siteName}`);

  // Check permissions
  const hasConfigWrite = config.permissions.data.some(
    p => p.path === 'CONFIG' && p.actions.includes('write')
  );
}

// Get path-specific config
const pageConfig = await getConfig('geometrixx', 'outdoors', 'products/landing-page-config');

Response

  • 200 (json)
{
  ":names": ["permissions", "settings"],
  ":type": "multi-sheet",
  "permissions": {
    "total": 1,
    "data": [
      {
        "path": "CONFIG",
        "actions": "write",
        "groups": "admins"
      }
    ]
  },
  "settings": {
    "total": 2,
    "data": [
      {
        "key": "site-name",
        "value": "Geometrixx Outdoors"
      },
      {
        "key": "theme",
        "value": "adventure"
      }
    ]
  }
}

Behavior Notes:

Error Responses:

Config Scopes

Organization and Path Hierarchy

Configs can be created at different levels:

  • Javascript
// Organization-level config
// Path: /config/{org}/{repo}/config
await createConfig('geometrixx', 'outdoors', 'config', orgConfig);

// Repository root config
// Path: /config/{org}/{repo}/site-config
await createConfig('geometrixx', 'outdoors', 'site-config', siteConfig);

// Directory-specific config
// Path: /config/{org}/{repo}/drafts/config
await createConfig('geometrixx', 'outdoors', 'drafts/config', draftsConfig);

// Page-specific config
// Path: /config/{org}/{repo}/products/landing-page-config
await createConfig('geometrixx', 'outdoors', 'products/landing-page-config', pageConfig);

Important: There is no automatic inheritance or cascade. Each config path is independent. To implement config inheritance, you must manually fetch and merge configs from different scopes in your application logic.

JSON Format Specifications

Multi-Sheet Format

Use for configs with multiple related data sets (permissions, settings, metadata, etc.):

  • json
{
  ":names": ["sheet1", "sheet2", "sheet3"],
  ":type": "multi-sheet",
  "sheet1": {
    "total": 2,
    "data": [
      { "key": "value" }
    ]
  },
  "sheet2": {
    "total": 1,
    "data": [
      { "key": "value" }
    ]
  }
}

Required fields:

Single-Sheet Format

Use for simple configs with one data set:

  • json
{
  ":sheetname": "permissions",
  ":type": "sheet",
  "total": 2,
  "data": [
    { "key": "value" }
  ]
}

Required fields:

Common Patterns

Site Configuration with Permissions

  • Javascript
const siteConfig = {
  ":names": ["permissions", "site", "seo"],
  ":type": "multi-sheet",
  "permissions": {
    "total": 3,
    "data": [
      { "path": "CONFIG", "actions": "write", "groups": "admins" },
      { "path": "/drafts", "actions": "read,write", "groups": "editors" },
      { "path": "/", "actions": "read", "groups": "public" }
    ]
  },
  "site": {
    "total": 5,
    "data": [
      { "key": "name", "value": "Geometrixx Outdoors" },
      { "key": "domain", "value": "outdoors.geometrixx.com" },
      { "key": "language", "value": "en" },
      { "key": "timezone", "value": "America/Los_Angeles" },
      { "key": "env", "value": "production" }
    ]
  },
  "seo": {
    "total": 3,
    "data": [
      { "key": "title", "value": "Geometrixx Outdoors - Adventure Gear" },
      { "key": "description", "value": "Premium outdoor equipment and apparel" },
      { "key": "keywords", "value": "outdoor, camping, hiking, adventure" }
    ]
  }
};

await createConfig('geometrixx', 'outdoors', 'config', siteConfig);

Update Config (Merge Pattern)

  • Javascript
async function updateConfigSheet(org, repo, path, sheetName, newData) {
  // 1. Get existing config
  const config = await getConfig(org, repo, path);

  if (!config) {
    throw new Error('Config not found');
  }

  // 2. Update specific sheet
  if (config[sheetName]) {
    // Merge or replace data
    config[sheetName].data = newData;
    config[sheetName].total = newData.length;
  } else {
    // Add new sheet
    config[sheetName] = {
      total: newData.length,
      data: newData
    };
    config[':names'].push(sheetName);
  }

  // 3. Save updated config
  return await createConfig(org, repo, path, config);
}

// Usage
await updateConfigSheet('geometrixx', 'outdoors', 'config', 'settings', [
  { "key": "theme", "value": "light" },
  { "key": "new-feature", "value": "enabled" }
]);

Best Practices

  1. Always include CONFIG permission - If your config has a permissions sheet, always include an entry for CONFIG write access
  2. Use consistent naming - Adopt a naming convention for config paths (e.g., config for org-level, {path}-config for path-specific)
  3. Validate before saving - Parse and validate JSON structure in your application before sending to the API
  4. Version your configs - Consider storing config backups or using version control patterns
  5. Separate concerns - Use different sheets for different types of configuration (permissions, settings, metadata)
  6. Document your schemas - Maintain documentation of expected fields and values for each config type