Agent workflows

What a careful AgentLayer client does.

These sanitized examples show contract behavior. They are not live records and they do not point to a public production service. Approved clients receive their base URL and access scope directly from CrowdAlpha.

Sanitized response shape

{
  "success": true,
  "data": {
    "schemaVersion": "crowdalpha.agent.v1",
    "asOf": "2026-05-04T20:00:00Z",
    "version": "agent_world_context_v1",
    "answerType": "grounded_world_context",
    "entity": {
      "entity_id": "CROWDALPHA_ENTITY_ID",
      "name": "Approved entity",
      "type": "world_entity"
    },
    "currentState": [
      {
        "key": "route_viability",
        "value": 0.42,
        "band": "CONSTRAINED",
        "confidence": 0.77,
        "uncertainty": 0.18
      }
    ],
    "latestTransitions": [
      {
        "key": "route_viability",
        "from": 0.8,
        "to": 0.42,
        "delta": -0.38
      }
    ],
    "compositeScores": [
      {
        "profileKey": "maritime_route_pressure",
        "score": 0.61,
        "band": "ELEVATED",
        "semantics": "pressure_high_is_risk",
        "status": "READY"
      }
    ],
    "evidence": [
      {
        "evidenceId": "observation:CROWDALPHA_EVIDENCE_ID",
        "observationId": "CROWDALPHA_EVIDENCE_ID",
        "sourceLabel": "world_observation",
        "collectedAt": "2026-05-04T19:54:00Z"
      }
    ],
    "contradictions": [
      {
        "id": "CROWDALPHA_CONTRADICTION_ID",
        "status": "OPEN"
      }
    ],
    "blockers": [],
    "status": "READY",
    "confidence": 0.77,
    "uncertainty": 0.18,
    "sourceRefs": [
      {
        "refType": "observation",
        "refId": "CROWDALPHA_EVIDENCE_ID",
        "evidenceId": "observation:CROWDALPHA_EVIDENCE_ID",
        "sourceType": "world_observation",
        "sourceId": "CROWDALPHA_EVIDENCE_ID",
        "sourceLabel": "world_observation",
        "stateVariable": "route_viability",
        "occurredAt": "2026-05-04T19:54:00Z",
        "publishedAt": "2026-05-04T19:54:00Z",
        "provenanceKeys": [
          "world_observation",
          "source_artifact"
        ]
      }
    ],
    "provenance": {
      "interface": "crowdalpha_agent_interface_v1",
      "truthLayer": "world_model",
      "authority": "stored_state_transitions",
      "llmGeneratedFactsAllowed": false
    },
    "redaction": {
      "applied": false,
      "rules": []
    },
    "entitlements": {
      "mode": "role_derived_v1",
      "actorRole": "USER",
      "requiredScopes": [
        "world.read",
        "evidence.read"
      ],
      "effectiveScopes": [
        "world.read",
        "evidence.read",
        "decision.read",
        "stream.read"
      ],
      "missingScopes": []
    }
  }
}

Recommended path

Carry the sources with the answer.

01

Find the canonical entity or package.

02

Read the current record and recent changes.

03

Fetch evidence before citing or acting.

04

Label discovery leads and blockers instead of certainty.

05

Use decision inputs when the result enters a workflow.

06

Preserve provenance, confidence, uncertainty, and redaction metadata.

Minimal agent loop

Read the record first. Check the evidence next.

The client checks access and redaction before it uses a result. If the response has no evidence reference, it does not invent one.

Illustrative TypeScript helper

async function readCrowdAlphaState(entityId: string) {
  const baseUrl = process.env.CROWDALPHA_API_BASE;
  if (!baseUrl) {
    throw new Error("Use the base URL from your approved handoff");
  }
  const headers = {
    Authorization: `Bearer ${process.env.CROWDALPHA_API_TOKEN}`,
    Accept: "application/json",
  };
  const parseCrowdAlphaError = (payload: any) => {
    const error = payload?.detail?.error ?? payload?.detail ?? payload?.error;
    return {
      code: error?.code ?? "UNKNOWN_ERROR",
      message: error?.message ?? "CrowdAlpha request failed",
      missingScopes: error?.missingScopes ?? [],
    };
  };

  const stateResponse = await fetch(
    `${baseUrl}/api/v1/state/entities/${encodeURIComponent(entityId)}`,
    { headers },
  );
  const body = await stateResponse.json();

  if (!stateResponse.ok || !body.success) {
    return {
      state: null,
      evidence: null,
      error: parseCrowdAlphaError(body),
    };
  }

  const state = body.data;

  if (state.redaction?.applied) {
    return { state, evidence: null, note: state.redaction.rules?.join(", ") };
  }

  const evidenceRef =
    state.evidence?.find(
      (row: any) =>
        typeof row?.evidenceId === "string" &&
        row.evidenceId.startsWith("observation:"),
    )?.evidenceId ??
    state.sourceRefs?.find(
      (ref: any) =>
        typeof ref?.evidenceId === "string" &&
        ref.evidenceId.startsWith("observation:"),
    )?.evidenceId ??
    state.sourceRefs?.find(
      (ref: any) =>
        ref?.refType === "observation" && typeof ref?.refId === "string",
    )?.refId;
  const evidenceResponse = evidenceRef
    ? await fetch(`${baseUrl}/api/v1/evidence/${encodeURIComponent(evidenceRef)}`, { headers })
    : null;

  return {
    state,
    evidence: evidenceResponse ? await evidenceResponse.json() : null,
  };
}

Error examples

Keep failures visible.

AgentLayer advertises `agent_error_model_v1` through capabilities, schemas, and OpenAPI. Clients should preserve codes, missing scopes, redaction, and retry policy instead of converting failures into unsupported answers.

401 auth envelope

Shared auth failures use the response-builder envelope shape.

{
  "detail": {
    "success": false,
    "error": {
      "code": "UNAUTHORIZED",
      "message": "Missing or invalid token"
    }
  }
}

403 scope guard

Direct AgentLayer guards preserve missing scopes for fail-closed clients.

{
  "detail": {
    "code": "AGENT_SCOPE_DENIED",
    "message": "Agent interface scope denied",
    "missingScopes": [
      "evidence.read"
    ]
  }
}

403 entitlement guard

Entitlement misses return a code instead of substituting generated state.

{
  "detail": {
    "code": "AGENT_ENTITLEMENT_DENIED",
    "message": "Agent entitlement denies this entity."
  }
}

403 package simulation guard

Scoped clients must treat hidden simulation result refs as a denial, not as visible branch data.

{
  "detail": {
    "code": "AGENT_ENTITLEMENT_DENIED",
    "message": "Agent entitlement does not allow this state-package simulation result."
  }
}

429 rate limit guard

Rate limits remain parseable; callers should retry by policy.

{
  "detail": {
    "code": "AGENT_RATE_LIMITED",
    "message": "Agent client is rate limited. Try again after 60 seconds."
  }
}

research or operations agent

Find a missing fact

Check the approved record and customer context for stale assumptions, missing evidence, or a contradiction that needs review.

monitoring agent

Understand what changed

Ask about an entity, place, market, or domain and return the recorded change with its time and source trail.

maritime agent

Inspect maritime activity

Bring together relevant context about vessels, ports, routes, trade, weather, infrastructure, ownership, and compliance without reducing maritime to one risk category.

industry or supply chain agent

Connect signals across domains

Follow a change across companies, infrastructure, commodities, policy, logistics, and other relevant parts of the Earth system.

customer agent

Brief a human owner

Return a concise answer with the supporting records and any limits, instead of filling gaps with generated certainty.

workflow agent

Watch for a real change

Read approved updates, check the evidence, and leave the decision to the customer workflow or human reviewer.

Read the record. Check its sources. Stop when the answer is not supported.

AgentLayer Contract Examples | CrowdAlpha