Analify Core

Overview

Three Core API domains have no external platform behind them — the data is Analify's own. They live under the same /api/core prefix and share its envelope and auth, but two conventions differ from the platform-mirror pages:

  1. Money here IS integer piasters (EGP × 100), matching the rest of the Analify API rather than a platform's unit.
  2. There is no "raw platform body" — data is Analify's own shape, and it is stable.

Base paths: /api/core/cogs · /api/core/organization · /api/core/integrations
Every request: requires ?organizationId=<uuid>.

API Endpoints

EndpointScopeDescription
GET /cogsfinance.costsList product costs
POST /cogsfinance.costsCreate / update one SKU's cost
GET /cogs/{sku}finance.costsGet one SKU's cost
DELETE /cogs/{sku}finance.costsRemove a SKU's cost
POST /cogs/bulkfinance.costsUpsert many SKUs at once
GET /cogs/coveragefinance.costsHow much of the catalogue is priced
GET /organizationsettings.generalOrganization profile
GET /organization/memberssettings.membersMembers and roles
GET /organization/invitationssettings.membersPending invitations
GET /organization/rolessettings.generalThe role registry
GET /integrationssettings.integrationsConnected platforms and their state

Product costs (COGS)

COGS is the input Analify cannot derive for you — and without it, profit is a guess. These endpoints are the programmatic way to keep it current (a nightly sync from your ERP, for example).

costPerUnit is an integer in piasters. 12500 means EGP 125.00, not EGP 12,500. Sending major units understates every cost 100× and silently inflates reported profit.

GET /api/core/cogs

Params: limit, offset, search, sort — one of sku · cost_asc · cost_desc · updated.

curl "https://analify.scalyax.ai/api/core/cogs?organizationId={organizationId}&limit=50&sort=cost_desc" \
  -H "Authorization: Bearer {anlfy_token}"

POST /api/core/cogs

Upserts one SKU. Body: sku, productName, costPerUnit (piasters, integer). All three are required — a missing field returns 400.

curl -X POST "https://analify.scalyax.ai/api/core/cogs?organizationId={organizationId}" \
  -H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
  -d '{
    "sku": "DEEP-COUPLES-AR",
    "productName": "Deep Couples",
    "costPerUnit": 12500
  }'

costPerUnit: 0 is valid and is stored, not treated as missing — a genuinely free item (a sample, a gift insert) is a real cost of zero. Only an absent or non-numeric field is rejected.

POST /api/core/cogs/bulk

Body: { items: [{ sku, productName, costPerUnit }] }. The array must be non-empty — an empty items returns 400 rather than succeeding as a no-op, because an empty bulk write is nearly always a caller bug.

curl -X POST "https://analify.scalyax.ai/api/core/cogs/bulk?organizationId={organizationId}" \
  -H "Authorization: Bearer {anlfy_token}" -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "sku": "DEEP-COUPLES-AR", "productName": "Deep Couples", "costPerUnit": 12500 },
      { "sku": "DEEP-FAMILY-AR", "productName": "Deep Family", "costPerUnit": 9900 }
    ]
  }'

GET /api/core/cogs/{sku} and DELETE /api/core/cogs/{sku}

A SKU with no cost on file returns 404 COGS_NOT_FOUND — distinct from a SKU priced at zero, which returns 200 with costPerUnit: 0.

GET /api/core/cogs/coverage

How much of the catalogue actually has a cost. Read this before trusting a profit figure: coverage is the gate between "your profit is EGP 5,023" and the truth that nobody priced half the catalogue.

curl "https://analify.scalyax.ai/api/core/cogs/coverage?organizationId={organizationId}" \
  -H "Authorization: Bearer {anlfy_token}"

Prefer these endpoints over Shopify's variant-cost when you want costs in Analify without writing to the store. Use PATCH /api/core/shopify/products/variant-cost instead when Shopify should be the system of record.


Organization

GET /api/core/organization

Name, slug, description, settings and timezone.

Billing state is deliberately stripped. credits and purchased_credits are removed from the response before it is serialized — an organization's spendable balance never leaves through this route. Read balances through the billing surfaces instead.

curl "https://analify.scalyax.ai/api/core/organization?organizationId={organizationId}" \
  -H "Authorization: Bearer {anlfy_token}"

A 404 ORG_NOT_FOUND means the id resolved to no organization.

GET /api/core/organization/members and …/invitations

Current members with their roles, and invitations still pending. Both carry personal data, so they sit on the tighter settings.members scope rather than settings.general.

GET /api/core/organization/roles

The role registry as defined in code — not org-scoped rows. The response is identical for every organization; it still requires organizationId, like every Core API route. Use it to render a role picker without hard-coding role names.


Integrations

GET /api/core/integrations

Which platforms this organization has connected, and the health of each. This is the cheapest discovery call in the whole API — a plain database read with no date range and no fan-out to any platform.

curl "https://analify.scalyax.ai/api/core/integrations?organizationId={organizationId}" \
  -H "Authorization: Bearer {anlfy_token}"

One row per connected account:

FieldMeaning
idThe integration UUID — what /api/analytics/integration/{id}/… routes take
platformmeta_ads · tiktok_ads · google_ads · google_analytics · shopify · bosta …
statusConnection state
account_id, account_nameThe account on the platform's side
connect_typeHow it was connected (OAuth, API key, …)
account_timezoneThe account's own timezone — why two platforms can disagree about "today"
last_synced_atLast successful sync
last_errorThe most recent failure, if any

Credentials are never returned. encrypted_credentials is excluded at the query level, not filtered afterwards — there is no request shape that returns it.

Use this to answer "is Bosta connected before I call a shipping route?" in one request, instead of calling the route and interpreting a *_NOT_CONNECTED error.


Error Shape

These domains use Analify's standard codes rather than a platform taxonomy:

CodeStatusMeaning
BAD_REQUEST400Malformed JSON body, missing required field, or empty items
COGS_NOT_FOUND404No cost data on file for that SKU
ORG_NOT_FOUND404The organization does not exist
{
  "success": false,
  "error": {
    "message": "sku, productName, and costPerUnit (piasters) are required",
    "code": "BAD_REQUEST"
  }
}

Did this page help you?