Skip to content

REST API

REST exposes the same read-only Data Layer contract as CLI and MCP under /v1. Use exactly one supported OAuth or machine credential. OAuth identities are server-managed.

Use https://api.argusfa.com/openapi.json for executable request schemas. Send either Authorization: Bearer <API-audience token> or X-Argus-API-Key as a header. With OAuth omit institution_id and caller_id from the JSON body. Apply the REST binding's parameter aliases and encodings: filters_json and sort_json become filters and sort JSON arrays; feature facts_json, nodes_json, and limits_json become facts, nodes, and limits JSON arrays/objects; observations_json becomes an observations JSON array. REST array parameters are arrays, not comma-separated strings.

Ordinary-user OAuth requests

Install the official wheel and run argus auth login, then argus auth status. The installed package's public CliOAuthProfile and CliOAuthClient also support REST clients: access_token() reads the matching OS credential store and refreshes an expiring API token. It returns None when login is required. Keep the token in process memory; do not print it, copy it into configuration, or export the credential store. This uses the API audience; it cannot authenticate MCP.

import json
from urllib.request import Request, HTTPRedirectHandler, build_opener
from argus.cli.oauth import CliOAuthProfile

profile = CliOAuthProfile()  # Official production issuer, client and API resource.
token = profile.client().access_token()
if token is None:
    raise RuntimeError("Run argus auth login first")

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, *args, **kwargs):
        return None

request = Request(
    profile.api_base_url + "/v1/entity-search",
    data=json.dumps({"query": "5493001KJTIIGC8Y1R12",
                     "purpose": "factual_lookup"}).encode(),
    headers={"Authorization": f"Bearer {token}",
             "Content-Type": "application/json",
             "User-Agent": "Argus REST client"},
    method="POST",
)
# Disable redirects so authorization is never forwarded to another origin.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
    envelope = json.load(response)

The LEI is a real GLEIF subject, not a demo issuer. This request shows the ordinary REST authentication path; its returned coverage, facts and evidence must still be checked. HTTP 200 or success=true alone does not establish a complete business result. Use the public Registry and OpenAPI to choose the actual REST endpoint and arguments for each capability. Preserve audit_id, check result_status and the expected record counts, and call the documented source-evidence endpoint for returned evidence references. A 401 requires login or refresh; a 403 requires the requested signed tool scopes or caller ownership. Do not retry an authorization failure with fabricated institution/caller IDs.

Requests are structured JSON. Common fields include purpose, as_of, and requires_redistribution; free-form execution text is not accepted. Tool-specific schemas are generated from the Registry and listed in Generated Interface Contracts.

The neutral session package endpoint accepts explicit market, session, session_date, and symbols. Universe and filter state belong to the caller or external configuration.

All successful tool calls return a machine-readable envelope containing a typed payload, evidence and governance metadata where applicable, plus an audit identifier. Missing coverage is coded as empty, partial, or unavailable.

Availability preflight

The prepared 1.1.8 agent_data_preflight implementation checks the authenticated caller's current target-tool policy for the actual interface and scopes. A known tool name is insufficient. For company_fact_snapshot and fundamental_facts, it performs bounded reads through their shared business boundary, producing ordinary target-call audit records. Pass the subjects those bindings accept as company IDs; ticker-to-company inference is not performed by preflight.

Each requested field must have visible evidence and temporal records for every subject. Duration intervals must cover the requested range without a gap; instant records prove only their instant. A partial or capped target result, late capture, missing subject, or unknown permission cannot yield preflight.allowed=true. Up to 32 subjects are probed; a larger request retains an explicit coverage gap and cannot pass. The result records measured time, observed subject count and latest known time without claiming a freshness SLO.

Other targets currently report target_query_arguments_not_verified rather than infer availability from unrelated filing data. Their target-specific probes remain unfinished. A successful preflight is a measurement at that call, and does not reserve provider quota or guarantee a later source revision.

Preflight returns an audit-specific metadata evidence locator. Once its audit is successful, source_evidence_lookup retrieves that caller's exact archived public metadata, with checksum verification and no internal storage address. Use a lookup cutoff after the measurement completed; the financial range under inspection may precede the time Argus computed the preflight. This projection proves the recorded measurement, and is not a new financial observation.

Evidence bundles from a real call

In the prepared 1.1.8 implementation, a nonempty result is archived only after permission, license and public-output governance. Its public source package ID is data_package: followed by that result's audit_id. Supply this ID as source_package_id to the Registry binding for evidence_bundle_export using the same authenticated caller and institution. The same rule applies to CLI and MCP results; there is no public data_package_id field to guess.

The export verifies the successful source audit, reads the actual persisted public result and checks its byte length and SHA-256. It returns the original facts and evidence plus a manifest containing the source package ID, checksum, byte length, counts and evidence IDs. The checksum covers the canonical UTF-8 JSON of the original governed result, not the input ID string or the new bundle wrapper. A source that was empty, unavailable, failed, belongs to another caller or was never archived cannot produce a verified bundle. Older 1.1.7 calls were not archived and cannot be reconstructed from their shortened audit summaries.

Keep the original JSON response to verify its checksum independently. The canonical input is the governed DataPackage in the envelope's result, excluding the envelope and the later bundle's manifest:

import hashlib
import json

source_package_id = "data_package:" + source_response["audit_id"]
original_bytes = json.dumps(
    source_response["result"], ensure_ascii=False, sort_keys=True,
    separators=(",", ":"),
).encode("utf-8")
expected_sha256 = hashlib.sha256(original_bytes).hexdigest()

Compare this value with the exported fact named evidence_bundle.content_hash_sha256. This snippet performs local verification; source_response must come from the actual successful authenticated call.

The source result's coverage status and license restrictions remain attached. include_restricted=true never expands the stored public projection or opens controlled source text. Evidence lookup uses each returned locator and the original result's effective_as_of; a later revision may require that historical cutoff. Internal object-storage addresses are never export destinations. These rules describe prepared source behavior; they do not establish deployment or complete data coverage.

There are no public endpoints for question answering, narratives, user-state mutation, performance reports, strategies, orders, accounts, or AI-agent orchestration. Removed endpoint mappings are available only through the Registry's structured major-version migration manifest.