logo
Fast Data StorageEdge Config

Edge Config

Prerequisites

Ensure you have the following ready:

  • A Novisurf account with access to the dashboard

  • An Edge Config store created from the Edge Config tab in your project dashboard

  • A scoped API key generated from the API Keys subtab of your store

What is Novisurf Edge Config?

Novisurf Edge Config is a persistent JSON configuration store. Unlike KV, entries have no TTL — they persist until you explicitly delete them. Each entry has a named key (e.g. firewallaccess) and a JSON value of any shape. It is designed for runtime configuration: feature flags, access control lists, A/B test parameters, and environment-specific settings that your edge workers or backend services read at runtime.

Create a store

Open the Edge Config tab in your Novisurf dashboard, type a store name in the input at the top of the sidebar, and press Enter or click +. The dashboard creates the store and returns a storeId that looks like:

ec_mystore_89daefd42eab

Copy the store ID from the sidebar — click the icon next to it, or use the copy button in the topbar once the store is selected.

Generate an API key

In the API Keys subtab of your store, generate a scoped key:

ScopeAllowed operations
readGET a single config, list all configs
writePUT (upsert) a config, DELETE a config
adminAll of the above

The raw key is shown once at generation time. Copy it immediately. It looks like:

kv_read_a1b2c3d4e5f6...
kv_write_a1b2c3d4e5f6...
kv_admin_a1b2c3d4e5f6...

Edge Config reuses the same API key format and X-KV-Key header as Novisurf KV. A key is scoped to a single store — it cannot be used across stores.

Authentication

All Edge Config API requests use a single header:

X-KV-Key: kv_write_a1b2c3d4e5f6...

No Authorization: Bearer header is needed when using a scoped API key. Bearer tokens (Appwrite JWTs) are only required for management operations (creating stores, listing stores, generating keys).

Quota is attributed to the store owner, not the caller. If you share a read key with a third-party service, their reads count against your account.

Base URL

https://configs.novisurf.top

Write a config entry

PUT /v1/ec/{storeId}/{key}
X-KV-Key: kv_write_...
Content-Type: application/json

{
  "value": { "enabled": true, "allowedIps": ["1.2.3.4"] }
}

The value field can be any JSON-serialisable type: object, array, string, number, or boolean.

curl -X PUT https://configs.novisurf.top/v1/ec/ec_mystore_89daefd42eab/firewallaccess \
  -H "X-KV-Key: kv_write_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -d '{"value": {"enabled": true, "allowedIps": ["1.2.3.4"]}}'

Response

{
  "ok": true,
  "key": "firewallaccess",
  "updatedAt": "2025-01-01T00:00:00.000Z"
}

Read a config entry

GET /v1/ec/{storeId}/{key}
X-KV-Key: kv_read_...
curl https://configs.novisurf.top/v1/ec/ec_mystore_89daefd42eab/firewallaccess \
  -H "X-KV-Key: kv_read_a1b2c3d4e5f6"

Response

{
  "ok": true,
  "key": "firewallaccess",
  "value": { "enabled": true, "allowedIps": ["1.2.3.4"] },
  "updatedAt": "2025-01-01T00:00:00.000Z"
}

Returns 404 if the key does not exist.

List all config entries in a store

Returns all keys and their values. Useful for bootstrapping your application config at startup.

GET /v1/ec/{storeId}
X-KV-Key: kv_read_...
curl https://configs.novisurf.top/v1/ec/ec_mystore_89daefd42eab \
  -H "X-KV-Key: kv_read_a1b2c3d4e5f6"

Response

{
  "ok": true,
  "configs": [
    {
      "key": "firewallaccess",
      "value": { "enabled": true, "allowedIps": ["1.2.3.4"] },
      "updatedAt": "2025-01-01T00:00:00.000Z"
    },
    {
      "key": "featureflags",
      "value": { "darkMode": true, "betaCheckout": false },
      "updatedAt": "2025-01-02T00:00:00.000Z"
    }
  ]
}

Delete a config entry

DELETE /v1/ec/{storeId}/{key}
X-KV-Key: kv_write_...
curl -X DELETE https://configs.novisurf.top/v1/ec/ec_mystore_89daefd42eab/firewallaccess \
  -H "X-KV-Key: kv_write_a1b2c3d4e5f6"

Usage in a Novisurf Functions

A common pattern is to fetch your entire config store at the start of a request and use it to drive runtime behaviour.

export default {
  async fetch(request, env) {
    // Fetch all configs once per request (or cache in KV/memory)
    const res = await fetch(
      `https://configs.novisurf.top/v1/ec/${env.EC_STORE_ID}`,
      { headers: { 'X-KV-Key': env.EC_READ_KEY } }
    );
    const { configs } = await res.json();

    // Build a lookup map
    const cfg = Object.fromEntries(configs.map((c) => [c.key, c.value]));

    // Use config values
    if (!cfg.firewallaccess?.enabled) {
      return new Response('Forbidden', { status: 403 });
    }

    return new Response('OK');
  },
};

For high-traffic workers, cache the config response in Novisurf KV or in-memory with a short TTL (e.g. 30 seconds) to avoid hitting the Edge Config API on every request.

Usage in a Deno / Node.js backend

const STORE_ID = process.env.EC_STORE_ID!;
const READ_KEY = process.env.EC_READ_KEY!;

async function getConfig(key: string) {
  const res = await fetch(
    `https://configs.novisurf.top/v1/ec/${STORE_ID}/${key}`,
    { headers: { 'X-KV-Key': READ_KEY } }
  );
  if (!res.ok) return null;
  const { value } = await res.json();
  return value;
}

// Example: read feature flags
const flags = await getConfig('featureflags');
if (flags?.betaCheckout) {
  // enable beta checkout flow
}

Error reference

StatusMeaning
401Missing or invalid auth header
403API key scope insufficient (e.g. using a read key for a write operation)
404Config key not found / store not found
400Missing or invalid value field in request body

Differences from KV

FeatureKVEdge Config
TTL / expiryRequired (min 60s)None — persists forever
StorageDisk (file per key)Postgres (JSONB)
Use caseEphemeral cache, sessionsPersistent config, feature flags
Value typeAny JSONAny JSON
Auth headerX-KV-KeyX-KV-Key (same)

Next steps