Developers

Build on Valivra.

Versioned JSON API for market-data records. Read the catalog, record discoveries, and pull news — with the same auth on every request.

https://valivra.com/api/v1

Send JSON bodies with Content-Type: application/json. All responses are JSON. Write endpoints operate on the global catalog only.

Authentication

Every request carries a credential in one of these headers. Missing or incorrect credentials return 401 {"error":"Unauthorized"}. Requests are denied outright when no shared code is configured on the server.

Authorization: Bearer <token>
X-Api-Key: <token>
  • Shared operator code — the app-administrator path for write endpoints, configured server-side and never stored in source.
  • Per-user token — any signed-in member creates a revocable token at /settings/api-tokens; it works exactly like the shared code. Unknown or revoked tokens are rejected.

Pagination and errors

List endpoints are paginated. page is 1-based; per_page accepts limit as an alias.

Resource Default Max
Companies2001000
Press release sources50100
Indices50100
Index constituents50100
News50100

Failures use a consistent shape:

Status When
400Missing required root key
401Bad or missing credential
404Unknown id
422Validation failure or blocked destroy
{"errors": ["Name can't be blank"]}

Endpoints

Resources

Companies

Market-data issuers. The index is a slim catalog — page it with q (name, CIK, symbol, sector, industry) and fetch show only when you need the full issuer record.

  • GET /api/v1/companies — slim catalog
  • GET /api/v1/companies/:id — full details
  • POST /api/v1/companies — create (wrap in company)
  • PATCH / PUT /api/v1/companies/:id — update
  • DELETE /api/v1/companies/:id — delete (fails if securities exist)

Company press release sources

One optional IR/newsroom source per company. Filter the list by company_id and status; create under a company_press_release_source root key. Typical write: create if the company has no source, otherwise PATCH it with URLs, status: "discovered", confidence, and notes.

  • GET /api/v1/company-press-release-sources
  • GET /api/v1/company-press-release-sources/:id
  • POST /api/v1/company-press-release-sources
  • PATCH / PUT /api/v1/company-press-release-sources/:id
  • DELETE /api/v1/company-press-release-sources/:id

Indices

Market indices (e.g. ^DJI, ^GSPC, ^VIX). Read-only. Filter by q, tracked, and with_constituents; show includes the latest quote.

  • GET /api/v1/indices
  • GET /api/v1/indices/:id

Index constituents

Members of an index. Read-only. Filter by index_id, security_id, provider, and linked.

  • GET /api/v1/index-constituents
  • GET /api/v1/index-constituents/:id

News

Market news articles, newest first, each tagged with the symbols it mentions. The list is filterable and paginated; create under a news root key.

  • GET /api/v1/news — list, newest first
  • GET /api/v1/news/:id — one article
  • POST /api/v1/news — create (wrap in news)

List filters

Parameter Meaning
symbol One or more tickers, comma or space separated. Matches articles mentioning any of them.
source Exact source: general_news, stock_news, press_release, wsj, barrons.
provider Exact provider: FMP or company_site.
category Exact category: general, stock, or tracked.
q Case-insensitive text match on title, summary, content, publisher, site, or symbols.
from / to Published-date range, YYYY-MM-DD, inclusive at both ends.
page / per_page Pagination; per_page defaults to 50 and caps at 100.

A source, provider, or category value outside the list above is ignored rather than rejected, and an unparseable date drops its bound — so a bad filter widens the result set instead of emptying it. Filters combine with AND.

Article fields

Every field except id, created_at, and updated_at is writable on create.

Field Notes
id Read-only.
title Required.
url Required, unique across articles.
published_at Required ISO 8601 timestamp. The sort key — newest first.
publisher Defaults to Wall Street Journal.
site Host or site name the article came from.
symbol Uppercased. Shorthand for a one-item symbols.
symbols Array of tickers, uppercased and deduped — one article can mention several companies. Wins over symbol, which is kept in step as the first entry.
summary Short abstract.
content Full text, when the source provides it.
image_url Lead image.
category Required. general · stock · tracked
source Required. general_news · stock_news · press_release · wsj · barrons
provider Required. FMP · company_site

Examples

# Recent stock news mentioning AAPL or MSFT
curl -sS "https://valivra.com/api/v1/news?symbol=AAPL,MSFT&category=stock&from=2026-07-01" \
  -H "Authorization: Bearer <token>"

# Record an article scraped from a company newsroom
curl -sS -X POST https://valivra.com/api/v1/news \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "news": {
      "title": "Acme Corp raises full-year guidance",
      "url": "https://www.acme.example/newsroom/guidance-2026",
      "published_at": "2026-07-02T11:00:00Z",
      "publisher": "Acme Corp",
      "site": "acme.example",
      "symbols": ["ACME", "ACME.B"],
      "summary": "Acme raised full-year revenue guidance on stronger demand.",
      "category": "stock",
      "source": "press_release",
      "provider": "company_site"
    }
  }'
{
  "news": [
    {
      "id": 3,
      "title": "Acme Corp raises full-year guidance",
      "url": "https://www.acme.example/newsroom/guidance-2026",
      "published_at": "2026-07-02T11:00:00.000Z",
      "publisher": "Acme Corp",
      "site": "acme.example",
      "symbol": "ACME",
      "symbols": ["ACME", "ACME.B"],
      "summary": "Acme raised full-year revenue guidance on stronger demand.",
      "content": null,
      "image_url": null,
      "category": "stock",
      "source": "press_release",
      "provider": "company_site",
      "created_at": "2026-07-02T11:00:00.000Z",
      "updated_at": "2026-07-02T11:00:00.000Z"
    }
  ],
  "pagination": { "page": 1, "per_page": 50, "total_count": 1, "total_pages": 1 }
}

A create stores exactly what you send and does not resolve entities against the company catalog, so tag the article yourself with symbols. Create returns 201 with the saved article; a validation failure returns 422 and an errors array.

Example

# List companies whose website you can crawl
curl -sS "https://valivra.com/api/v1/companies?per_page=1000" \
  -H "Authorization: Bearer <token>"

# Record a discovered IR feed
curl -sS -X POST https://valivra.com/api/v1/company-press-release-sources \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "company_press_release_source": {
      "company_id": 1,
      "status": "discovered",
      "list_url": "https://www.acme.example/newsroom",
      "feed_url": "https://www.acme.example/newsroom/rss.xml",
      "confidence": 85,
      "discovery_notes": "RSS link on newsroom page"
    }
  }'

Full field reference — writable attributes, enums, and response shapes — lives in docs/api_v1.md in the repo. Questions? [email protected].