Vconnct Developers

Get started

Authenticate and call DevKit Gateway V5 endpoints.

Get started with Gateway V5

All signed V5 endpoints use a project API key and its Gateway secret. The API key determines the owning project and organization on the server. Do not send project_id, organization_id, or similar authority fields to select data from another project.

Keep secrets private

Never put a Gateway secret in browser code, a mobile app, source control, logs, or support tickets. Store it only in a server-side secret manager.

Required headers

Every signed request must include these headers:

HeaderValue
api-keyYour project API key
timestampCurrent Unix timestamp in seconds
hash-signatureHex HMAC-SHA256 signature described below

Idempotency-Key is reserved for future write endpoints. Do not send it to the current read-only GET endpoints.

Sign the exact request

V5 uses the DK-HMAC-V5-1 profile. Sign the exact bytes below, in this order:

DK-HMAC-V5-1\n
HTTP_METHOD\n
REQUEST_TARGET\n
TIMESTAMP\n
IDEMPOTENCY_KEY\n
RAW_BODY
  • HTTP_METHOD is uppercase, for example GET.
  • REQUEST_TARGET begins with / and includes the query string exactly as sent, for example /api/v5/requests?limit=20.
  • TIMESTAMP is the same value sent in the timestamp header.
  • IDEMPOTENCY_KEY is empty for the current V5 GET endpoints.
  • RAW_BODY is the unmodified request body. It is empty for GET requests.
  • The timestamp must be within the server’s allowed clock skew (five minutes by default).

The server never uses a client-supplied project or organization identifier as authority. A valid key always resolves to its own project. An unknown key, wrong secret, stale timestamp, or invalid signature receives the same safe 401 VC_UNAUTHORIZED response so secrets cannot be guessed.

Node.js example

import crypto from 'node:crypto';

const baseUrl = process.env.DEVKIT_BASE_URL;
const apiKey = process.env.DEVKIT_V5_API_KEY;
const secret = process.env.DEVKIT_V5_SECRET;
const method = 'GET';
const target = '/api/v5/keys';
const timestamp = Math.floor(Date.now() / 1000).toString();
const rawBody = '';

const canonical = [
  'DK-HMAC-V5-1',
  method,
  target,
  timestamp,
  '',
  rawBody,
].join('\n');

const signature = crypto
  .createHmac('sha256', secret)
  .update(canonical, 'utf8')
  .digest('hex');

const response = await fetch(`${baseUrl}${target}`, {
  method,
  headers: {
    'api-key': apiKey,
    timestamp,
    'hash-signature': signature,
  },
});

console.log(await response.json());

Postman setup

Create these collection variables (or environment variables):

VariableInitial value
base_urlYour DevKit base URL, such as http://127.0.0.1:5000
v5_api_keyYour V5 project API key
v5_secretThe matching Gateway secret

Add the following collection-level Pre-request Script to the V5 folder. Individual requests inherit it.

const method = pm.request.method.toUpperCase();
const timestamp = Math.floor(Date.now() / 1000).toString();
const requestUrl = pm.variables.replaceIn(pm.request.url.toString());
const url = new URL(requestUrl);
const target = `${url.pathname}${url.search}`;
const rawBody = pm.request.body?.raw || '';
const retryKey = '';
const canonical = [
  'DK-HMAC-V5-1',
  method,
  target,
  timestamp,
  retryKey,
  rawBody,
].join('\n');

const apiKey = pm.variables.get('v5_api_key');
const secret = pm.variables.get('v5_secret');
const signature = CryptoJS.HmacSHA256(canonical, secret).toString(CryptoJS.enc.Hex);

pm.request.headers.upsert({ key: 'api-key', value: apiKey });
pm.request.headers.upsert({ key: 'timestamp', value: timestamp });
pm.request.headers.upsert({ key: 'hash-signature', value: signature });
pm.request.headers.remove('secret-key');
pm.request.headers.remove('key');

The GET /api/v5/openapi.json request is public and does not need this script.

Endpoint behavior

EndpointExpected successful result
GET /api/v5/keysdata.current shows the active key metadata; data.overlap is populated only during a rotation overlap. Secrets are never returned.
GET /api/v5/usageReturns organization-level usage that belongs to the key’s organization. Pay-as-you-go fields appear only for pay-as-you-go organizations; plan usage can explicitly be unavailable.
GET /api/v5/limitsReturns known organization entitlements. Missing providers are represented as unavailable, never invented quotas.
GET /api/v5/requestsReturns safe request diagnostics. If diagnostics are not configured, returns { "availability": "unavailable", "items": [] }.

Successful signed responses use a { "data": ... } envelope and include:

Response headerMeaning
X-Gateway-Request-IDSupport-safe ID to share with DevKit support.
X-Gateway-Requests-UsedInformational request count, or unavailable when its cache is unavailable. It is not a quota.

Errors

StatusCodeMeaning
401VC_UNAUTHORIZEDAPI key, secret/signature, or timestamp was not accepted. Confirm the key/secret pairing, system clock, exact target, and raw body.
403VC_GATEWAY_PROJECT_SUSPENDEDThe authenticated project is suspended.
404VC_GATEWAY_DISABLEDGateway V5 is disabled in this environment.
404VC_RESOURCE_NOT_FOUNDThe requested V5 resource does not exist.
503VC_GATEWAY_UNAVAILABLEA required downstream service is temporarily unavailable. Retry later.

Test checklist

  1. Call /api/v5/openapi.json; expect 200 while V5 is enabled.
  2. Send GET /api/v5/keys using the V5 folder script; expect 200 and a data envelope without a secret.
  3. Change v5_secret temporarily; expect 401 VC_UNAUTHORIZED.
  4. Set a timestamp more than five minutes old; expect 401 VC_UNAUTHORIZED.
  5. Alter the request query after the signature is created; expect 401 VC_UNAUTHORIZED.
  6. Call /api/v5/requests; availability: unavailable with an empty items array is valid until diagnostics are configured.