Developer Portal

Liquidity Checker API Reference

Overview

The Ediphy Liquidity Checker API enables programmatic access to our collaborative trading blotter system, allowing trading teams to manage declared interest, monitor liquidity conditions, and seamlessly transition to firm order execution.

Product Coverage: Fixed Income Bonds (Corporate Credit, Government, Emerging Markets)

Why the Liquidity Checker API?


1. Key Concepts

1.1 Interest Lifecycle

The Liquidity Checker manages declared interest — bonds you're interested in trading but haven't yet committed to as firm orders. Interest progresses through states based on user actions and market conditions.

Interest States (Firmness):

State Description
Inactive Interest exists but not actively monitored for opportunities
Soft Active interest, system monitors for favorable liquidity conditions
Firm Ready to trade — creates a live trading ticket in the EMS
Filled Goal quantity has been fully executed
Overfilled Executed quantity exceeds the declared goal (only possible if goal is reduced during execution)
Workflow

Typical flow: Add interest as Soft → Monitor liquidity indicators → When conditions are favorable, transition to Firm → Order executes via EMS → Interest becomes Filled.


1.2 User vs Team Scope

The blotter supports two visibility modes:

User Mode (Default)

Team Mode

Note

Team mode enables collaborative workflows where multiple traders can monitor and respond to the same set of trading opportunities.


1.3 Provenance Tracking

Every interest record tracks its provenance — the source of its most recent update:

Provenance Description
sync Created or updated via CSV upload / batch API
gui Created or updated via web interface or single-record API

Why provenance matters:

Provenance Override:

By default, when an API sync updates a record that was previously modified via GUI (prov: "gui"), certain fields may be preserved to prevent stale OMS data from overwriting recent manual changes.

To force an update regardless of provenance (when your OMS has authoritative data), use the force_overwrite: true flag:

JSON
{ "inst_id": "US912828ZT77", "client_id": "my-order-001", "limit": 99.00, "force_overwrite": true }

When force_overwrite: true:

Important

Use force_overwrite carefully. It overrides any manual changes made by traders via the UI. Ensure your OMS has the authoritative data before using this flag.


1.4 Firm Orders and EMS Integration

When interest transitions to Firm status, the Liquidity Checker creates a live trading ticket in the Execution Management System (EMS). At this point, the order becomes visible and monitorable in both the Liquidity Checker and the EMS API/GUI.

Cross-System Visibility:

System What You See Use Case
Liquidity Checker High-level execution status: qty_traded, trading_status, firmness_pres Monitor execution progress alongside other soft/inactive interest on your blotter
EMS API/GUI Full order lifecycle: live quotes, child orders, fills, routing decisions, execution quality Detailed order management and execution monitoring

Linking Records Across Systems:

The linked_interest_id field ties the two systems together:

Monitoring Strategy

After calling /go-firm, monitor execution via both systems: - Use Liquidity Checker WebSocket or polling for blotter-wide status updates (see Section 6) - Use EMS API for real-time fill notifications, routing decisions, and order state changes

The Liquidity Checker provides context ("which of my interests are actively trading?"), while the EMS provides depth ("what's happening with this specific order?").

Note

When an order completes execution, the interest firmness transitions to Filled (or Overfilled if the goal was reduced mid-execution). The interest remains on the blotter for audit purposes and can be set back to Soft or Inactive if needed.


1.5 Interest Identification

Each interest record has multiple identifiers serving different purposes:

Field Scope Description
interest_id System-wide Unique system-generated identifier (format: INTEREST_{uuid})
client_id Per-user Client's internal order/reference ID. Used to correlate with external OMS.
inst_id Instrument ISIN of the bond (e.g., US912828ZT77)

Client ID Behavior:

Important

Re-syncing with the same client_id updates the existing interest rather than creating a duplicate. This is intentional and enables OMS synchronization workflows.


1.6 Data Enrichment

The Liquidity Checker enriches each interest record with data from multiple sources to help traders assess market conditions and identify optimal execution windows.

1.6.1 MiFID Post-Trade Data

Market activity data derived from regulatory post-trade reporting (MiFID II transparency regime):

Field Description
notional_amount_usd Total traded volume in USD over the last 60 days
count Total trade count over the last 60 days
med_y Median traded yield from recent transactions
fairmark_price Ediphy's dynamic end-of-day mark price
fairmark_date Date of the most recent mark
Data Source

MiFID post-trade data is sourced from regulatory trade reports and updated daily. This provides an objective view of recent market activity independent of any single dealer's flow.

1.6.2 Liquidity Scores

Proprietary liquidity metrics calculated from historical trading patterns:

Trade Count Metrics:

Metric Description
tc5 Number of trades in the last 5 days
tc20 Number of trades in the last 20 days

Lookback Metrics (Lower = More Liquid):

Metric Description
lb5 Days of lookback required to find 5 trades
lb20 Days of lookback required to find 20 trades
lb50 Days of lookback required to find 50 trades
lb1mm Days of lookback required to accumulate 1MM USD volume
lb10mm Days of lookback required to accumulate 10MM USD volume
lb50mm Days of lookback required to accumulate 50MM USD volume
Interpreting Lookback Metrics

Lookback metrics indicate how "deep" into history you need to go to find meaningful trading activity. A bond with lb5 = 2 (found 5 trades within 2 days) is more liquid than one with lb5 = 30 (took 30 days to find 5 trades). Lower values indicate more liquid instruments.

Alternative Instruments:

Metric Description
alt_count Number of liquid alternative instruments available

The system identifies similar bonds (same issuer, comparable maturity, similar characteristics) that may offer better liquidity if your target instrument is illiquid.

1.6.3 Live Market Data

Real-time pricing from Ediphy's trading venues:

Field Description
livemid Current live mid-price (when available from active quoting)
flags_tradable Whether the instrument is currently available for trading on Ediphy

1.6.4 Liquidity Check Status

The liq_check_status field provides a composite assessment combining the above metrics:

Status Meaning Typical Conditions
CAN TRADE NOW High liquidity, favorable conditions Recent trades, good volume, active market
TRY NOW Moderate liquidity, worth attempting Some recent activity, may find counterparty
WAIT Low liquidity, unfavorable conditions Sparse trading, consider waiting or alternatives
ENTER INFO Missing required fields Side or quantity not specified
Note

The liquidity status is recalculated periodically as market conditions change. WebSocket subscribers receive liquidity_update messages when status changes.


2. Authentication & Authorization

2.1 Authentication

The API uses Bearer token authentication. Include your API key in the Authorization header:

Authorization: Bearer <api_key>

API keys are managed through the Ediphy client portal. See the EMS Client API documentation for details on key management and rotation.

2.2 Required Permissions

Permission Description
ems.trader Required to add/update/remove interest
blotter.team.view View team blotter (all users in organization)
blotter.team.update Modify another user's interest

3. API Design

3.1 Base URL Structure

Production:  https://api.ediphy.io/blotter/v1
Sandbox:     https://api-sandbox.ediphy.io/blotter/v1

3.2 Common Headers

Request:

Content-Type: application/json
Authorization: Bearer <api_key>

Response:

Content-Type: application/json
X-Ediphy-Request-Id: <uuid>

3.3 Error Response Format

JSON
{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid ISIN format", "field": "inst_id", "request_id": "req_abc123" } }

Error Codes:

Code Description
AUTHENTICATION_FAILED Invalid or missing credentials
PERMISSION_DENIED Not authorized for action
VALIDATION_ERROR Invalid request parameters
INVALID_ISIN ISIN format invalid or unrecognized
INVALID_VERB Verb must be buy, sell, or null
INVALID_FIRMNESS Firmness must be Soft, Inactive, or null
INVALID_QUANTITY Quantity must be a positive number
INVALID_LIMIT Limit price must be a positive number
INTEREST_NOT_FOUND Interest record does not exist
RATE_LIMIT_EXCEEDED Too many requests
INTERNAL_ERROR Server-side issue

3.4 HTTP Status Codes

Status Code Meaning When Used
200 OK Success Request processed successfully
400 Bad Request Malformed request Invalid JSON, missing required fields
401 Unauthorized Authentication failed Invalid/missing credentials
403 Forbidden Permission denied Valid auth but not authorized for action
404 Not Found Resource not found Unknown interest_id
429 Too Many Requests Rate limit exceeded See rate limiting section
500 Internal Server Error Server error Unexpected failure

4. Interest Endpoints

4.1 Add or Update Interest

POST /interest

Creates new interest or updates existing interest for a bond. If interest already exists for the (owner_user, client_id) combination, the existing record is updated.

Request Body

JSON
{ "inst_id": "US912828ZT77", "client_id": "my-order-001", "verb": "buy", "qty": 5000000, "limit": 99.50, "firmness": "Soft", "comment": "Opportunistic add" }

Field Definitions

Field Required Type Description
inst_id Yes string ISIN of the bond. Must be a valid 12-character ISIN.
client_id No string Client's internal reference ID. If omitted, system generates a random 8-character ID. Used to identify the interest for subsequent updates.
verb No string Trade direction: "buy" or "sell". Can be set later via update.
qty No integer Goal quantity in base currency units. E.g., 5000000 for 5MM. Can be set later via update.
limit No number Price limit. Can be set later via update.
firmness No string Interest state: "Soft" (default), "Inactive". To transition to "Firm", use POST /interest/{interest_id}/go-firm.
comment No string Free-form note for reference (e.g., "Recommended by research").
force_overwrite No boolean If true, updates all provided fields regardless of current provenance. Sets prov: "sync" on the record. Default: false. See Provenance Override below.
Quantity Units

All quantities are in base currency units (not millions) in both requests and responses. For example, 5000000 represents 5MM USD notional. This applies to qty, qty_traded, and all quantity-related fields throughout the API.

Response (Success - 200 OK)

JSON
{ "status": "success", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "client_id": "my-order-001", "inst_id": "US912828ZT77", "message": "Interest added successfully" }

Update Semantics

When updating existing interest:

JSON
{ "inst_id": "US912828ZT77", "client_id": "my-order-001", "limit": 99.75 }

This updates only the limit price; verb, qty, firmness, and comment remain unchanged.

Firmness Preservation

When re-syncing via batch upload, firmness set via the GUI is preserved. This allows traders to manually set firmness while automated systems sync quantity and limit updates.


4.2 Remove Interest

POST /interest/remove

Marks interest as Inactive with status Inactive. The record is not deleted but is excluded from active blotter views.

Request Body

JSON
{ "inst_id": "US912828ZT77", "client_id": "my-order-001" }
Field Required Description
inst_id Yes ISIN of the bond
client_id Yes Client's reference ID for the interest to remove

Response (Success - 200 OK)

JSON
{ "status": "success", "message": "Removed my-order-001" }
Note

Removing interest sets status: "Inactive". The record remains in the audit trail. To permanently clear all interest, use the Clear All endpoint.


4.3 Clear All Interest

POST /interest/clear-all

Removes all active interest for the authenticated user. Team administrators with appropriate permissions can clear interest for other users.

Request Body (Optional)

JSON
{ "on_behalf_of_ediphy_user": "jsmith", "on_behalf_of_ediphy_org": "acme-trading" }
Field Required Description
on_behalf_of_ediphy_user No Clear interest for this user (requires admin permission)
on_behalf_of_ediphy_org No Clear interest for this organization (requires admin permission)

If no parameters provided, clears all interest for the authenticated user.

Response (Success - 200 OK)

JSON
{ "status": "success", "message": "Cleared" }
Important

This operation is immediate and cannot be undone. All active interest for the specified scope is marked as inactive.


4.4 Batch Upload

POST /interest/batch

Upload multiple interest records in a single request. Ideal for syncing with external order management systems.

Request Body

JSON
{ "mode": "replace", "force_overwrite": false, "rows": [ { "inst_id": "US912828ZT77", "client_id": "order-001", "verb": "buy", "qty": 5000000, "limit": 99.50 }, { "inst_id": "US037833EK23", "client_id": "order-002", "verb": "sell", "qty": 10000000, "limit": 101.25 } ] }

Batch-Level Parameters

Field Required Description
mode No Upload mode: "replace" (default) or "merge". See below.
force_overwrite No If true, updates all fields regardless of provenance. Default: false.
rows Yes Array of interest records to upload.

Upload Modes:

Mode Behavior
replace Removes all existing sync-sourced entries for the user, then inserts the batch. This is the default and enables full OMS synchronization.
merge Upserts records by client_id. Existing entries not in the batch are preserved. Use this when multiple systems sync different subsets of interest.

Field Definitions (per row)

Field Required Description
inst_id / isin Yes ISIN of the bond (either field name accepted)
client_id No Client's internal reference ID
verb No "buy" or "sell"
qty / quantity No Goal quantity in base currency units
limit No Price limit
firmness No "Soft" or "Inactive"
comment No Free-form note

Response (Success - 200 OK)

JSON
{ "status": "success", "message": "ISIN list uploaded successfully.", "rows_processed": 2 }

Batch Upload Semantics

Replace Mode

In replace mode (default), batch uploads remove all previous sync-sourced entries for the user before inserting. Only the records in the current batch will have prov: "sync" after upload.

Example workflow (replace mode):

  1. User has 10 interest records from previous sync
  2. User uploads batch with 8 records (mode: replace)
  3. Result: 8 records from new batch (sync), plus any GUI-modified records preserved

Example workflow (merge mode):

  1. User has 10 interest records from previous sync
  2. User uploads batch with 3 records (mode: merge)
  3. Result: 3 records upserted, 7 original records preserved
Multi-System Sync

Use merge mode when multiple internal systems sync different instruments to the same user's blotter. For example, a Rates algo and Credit algo can coexist without overwriting each other's entries.

GUI modifications (firmness changes made via UI) are preserved across syncs because they have prov: "gui". Use force_overwrite: true to override this behavior.


4.5 Get Interest (User Scope)

GET /interest

Returns all active interest for the authenticated user, enriched with liquidity metrics and reference data.

Query Parameters

Parameter Description
status Filter by status: Active (default), Inactive
inst_id Filter by ISIN
verb Filter by side: buy, sell
firmness Filter by firmness: Soft, Inactive, Firm

Response (Success - 200 OK)

JSON
{ "interest": [ { "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "client_id": "my-order-001", "inst_id": "US912828ZT77", "short_name": "T 2.5 05/15/30", "legal_name": "US TREASURY N/B", "currency_rd": "USD", "maturity": "2030-05-15", "verb": "buy", "qty": 5000000, "limit": 99.50, "firmness": "Soft", "firmness_pres": "Soft", "liq_check_status": "CAN TRADE NOW", "livemid": 99.625, "flags_tradable": true, "tc5": 12, "lb5": 2, "lb20": 5, "lb1mm": 3, "lb10mm": 8, "alt_count": 4, "prov": "gui", "owner_user": "jsmith", "ts_captured": "2025-01-15T10:30:00.123Z", "ticket_id": null, "qty_traded": 0, "ticket_count": 0 } ] }

Key Response Fields

Field Description
interest_id System-generated unique identifier
client_id Client's reference ID
inst_id ISIN
short_name Bond short name (e.g., "T 2.5 05/15/30")
legal_name Issuer legal name
currency_rd Currency code
maturity Maturity date
verb Trade direction (buy/sell)
qty Goal quantity in base currency units
limit Price limit
firmness Raw firmness state
firmness_pres Presentation firmness (accounts for trading state)
liq_check_status Liquidity indicator
livemid Current mid-price
flags_tradable Whether instrument is available for trading on Ediphy
tc5, lb5, etc. Liquidity metrics (see Section 1.6)
alt_count Number of liquid alternatives
prov Provenance (sync or gui)
owner_user Username who owns this interest
ts_captured Timestamp of last update
ticket_id Active trading ticket ID (if firm)
qty_traded Quantity already executed (base currency units)
ticket_count Number of tickets created for this interest
Note

All quantities (requests and responses) are in base currency units. For example, 5000000 represents 5MM.


4.6 Get Interest (Team Scope)

GET /interest/team

Returns all active interest for the authenticated user's organization. Requires blotter.team.view permission.

Query Parameters

Same as user scope endpoint.

Response (Success - 200 OK)

Same structure as user scope, but includes interest from all team members. Each record includes owner_user to identify the owner.


4.7 Get Latest Changes

GET /interest/latest

Returns the most recent changes to interest records within the current hour. Useful for polling updates without fetching the full blotter.

Response (Success - 200 OK)

JSON
{ "changes": [ { "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "inst_id": "US912828ZT77", "status": "Active", "verb": "buy", "qty": 5000000, "limit": 99.75, "firmness": "Soft", "ts_captured": "2025-01-15T10:45:00.123Z" } ], "timestamp": "2025-01-15T10:46:00.000Z" }
Usage

Poll this endpoint every few seconds to receive incremental updates. Compare ts_captured to detect new changes since your last poll.


5. Trading Integration

5.1 Transitioning to Firm

Interest can transition to Firm via the API using the POST /interest/{interest_id}/go-firm endpoint or via the trading cockpit UI. The transition:

  1. Validates trading permissions
  2. Applies price protection settings
  3. Creates an EMS order linked to this interest

Workflow (API):


1. Add interest via API (firmness: "Soft")
2. Monitor liq_check_status via polling or WebSocket
3. When conditions favorable, call POST /interest/{interest_id}/go-firm
4. System creates EMS order with linked_interest_id
5. Interest shows ticket_id, firmness_pres: "FIRM"
6. Fills execute via EMS, qty_traded updates
7. When qty_traded >= qty, firmness_pres becomes "FILLED"

Workflow (UI):


1. Add interest via API (firmness: "Soft")
2. Monitor liq_check_status via polling or WebSocket
3. When conditions favorable, user clicks "Go Firm" in UI
4. System creates EMS order with linked_interest_id
5. Same as above...

5.2 Linked Ticket Fields

When interest has an active trading ticket:

Field Description
ticket_id Active EMS ticket identifier
trading_limit Current limit on the live ticket
trading_mkt_quantity Remaining quantity working in market
trading_status Ticket status
trading_user User who owns the firm order
qty_traded Total quantity filled across all tickets
ticket_count Number of tickets created for this interest

5.3 Actions Field

The actions field in the response indicates available UI actions:

Value Meaning
Go Firm Interest is soft, can transition to firm
Update Firm Interest has active ticket, can modify

5.4 Go Firm Endpoint

POST /interest/{interest_id}/go-firm

Transitions soft interest to a firm order. Creates an EMS order linked to this interest record.

Path Parameters

Parameter Description
interest_id The interest to transition (e.g., INTEREST_7f3a9b2c-...)

Request Body (Optional)

JSON
{ "limit": 99.50, "time_in_force": "GTT", "expire_at": "2025-01-15T16:00:00Z", "price_protection": "market" }
Field Required Description
limit No Override the interest's limit price for the firm order
time_in_force No "GTT" (default), "GTC", "EOD"
expire_at No Expiry time (required if time_in_force is GTT)
price_protection No Price protection level: "passive", "market" (default), "aggressive", "off"

If no body is provided, the order uses the interest's existing limit and default time-in-force settings.

Response (Success - 202 Accepted)

JSON
{ "status": "success", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "order_id": "ord_abc123", "ticket_id": "TICKET_xyz789", "message": "Interest transitioned to firm. EMS order created.", "links": { "interest": "/interest/INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "order": "https://api.ediphy.io/ems/v1/orders/ord_abc123" } }

Error Responses

Status Code Description
400 MISSING_REQUIRED_FIELDS Interest missing verb or qty
400 ALREADY_FIRM Interest already has an active ticket
403 PERMISSION_DENIED Not authorized to trade this instrument
404 INTEREST_NOT_FOUND Interest does not exist
Monitoring

After going firm, monitor the order via both the Liquidity Checker (interest updates show qty_traded, trading_status) and the EMS API (full order state, fills). The linked_interest_id field on the EMS order ties them together.


6. WebSocket Streaming

6.1 Overview

For real-time blotter updates, connect to the WebSocket stream. Updates are pushed when any interest record changes.

Production:  wss://api.ediphy.io/blotter/v1/stream
Sandbox:     wss://api-sandbox.ediphy.io/blotter/v1/stream

6.2 Connection & Authentication

Connect to the WebSocket endpoint and send an authentication message within 5 seconds:

JSON
{"type": "auth", "api_key": "<api_key>"}

Server response (success):

JSON
{ "type": "connected", "session": "2025-01-15", "scope": "user", "timestamp": "2025-01-15T10:30:00.123Z" }

6.3 Subscribe to Team Updates

After authentication, optionally subscribe to team-wide updates:

JSON
{"type": "subscribe", "scope": "team"}

Server response:

JSON
{ "type": "subscribed", "scope": "team", "timestamp": "2025-01-15T10:30:01.123Z" }

Requires blotter.team.view permission.

6.4 Heartbeat Protocol

Both client and server must send heartbeats to maintain the connection.

Direction Interval Timeout
Client → Server Every 30 seconds 90 seconds
Server → Client Every 30 seconds 90 seconds

Client heartbeat:

JSON
{"type": "heartbeat"}

Server heartbeat:

JSON
{"type": "heartbeat", "timestamp": "2025-01-15T10:30:00.123Z"}

6.5 Server Messages

Interest Update

Sent when any interest record changes:

JSON
{ "type": "interest_update", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "timestamp": "2025-01-15T10:32:15.789Z", "data": { "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "inst_id": "US912828ZT77", "short_name": "T 2.5 05/15/30", "verb": "buy", "qty": 5000000, "limit": 99.75, "firmness": "Soft", "liq_check_status": "CAN TRADE NOW", "owner_user": "jsmith", "ts_captured": "2025-01-15T10:32:15.789Z" } }

Interest Removed

Sent when interest is removed or marked inactive:

JSON
{ "type": "interest_removed", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "timestamp": "2025-01-15T10:35:00.123Z" }

Liquidity Update

Sent when liquidity metrics change (batched, typically every few seconds):

JSON
{ "type": "liquidity_update", "timestamp": "2025-01-15T10:32:20.000Z", "updates": [ { "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "liq_check_status": "CAN TRADE NOW", "livemid": 99.65, "tc5": 13 } ] }

Trading Update

Sent when trading state changes (ticket created, fill received):

JSON
{ "type": "trading_update", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "timestamp": "2025-01-15T10:40:00.123Z", "data": { "ticket_id": "TICKET_abc123", "firmness_pres": "FIRM", "qty_traded": 2500000, "trading_status": "WORKING" } }

6.6 Reconnection

If the WebSocket connection drops:

  1. Wait 1 second, then attempt reconnect
  2. On failure, use exponential backoff (2s, 4s, 8s, max 30s)
  3. After reconnecting, call GET /interest to sync state
  4. Resume normal operation
Note

The WebSocket stream does not replay missed messages. After reconnection, clients must use the REST API to query current state.


7. CSV File Format

7.1 Supported Formats

The batch upload endpoint and UI sync feature accept:

7.2 Required Columns

Column Description
isin ISIN of the bond (required)

7.3 Optional Columns

Column Description
client_id Your internal order/reference ID
verb buy or sell
quantity Goal quantity in base currency units
limit Price limit

7.4 Example CSV

CSV
isin,client_id,verb,quantity,limit US912828ZT77,order-001,buy,5000000,99.50 US037833EK23,order-002,sell,10000000,101.25 XS1234567890,order-003,buy,2000000,
Column Mapping

The UI provides automatic column mapping with fuzzy matching. Column headers like "ISIN", "Isin", "isin" are all recognized. You can also manually map columns if automatic detection fails.


8. Client Integration Patterns

8.1 OMS Synchronization

Sync your internal order management system with the Liquidity Checker:

PYTHON
import requests import csv API_BASE = "https://api.ediphy.io/blotter/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } # Export orders from your OMS def export_from_oms(): # Your OMS export logic return [ {"isin": "US912828ZT77", "client_id": "ORD-001", "verb": "buy", "qty": 5000000}, {"isin": "US037833EK23", "client_id": "ORD-002", "verb": "sell", "qty": 10000000}, ] # Sync to Liquidity Checker def sync_to_blotter(): orders = export_from_oms() payload = {"rows": orders} response = requests.post( f"{API_BASE}/interest/batch", json=payload, headers=headers ) response.raise_for_status() print(f"Synced {len(orders)} orders") # Run sync periodically (e.g., every 5 minutes) sync_to_blotter()

8.2 Liquidity Monitoring

Monitor liquidity conditions and alert when favorable:

PYTHON
import requests import time API_BASE = "https://api.ediphy.io/blotter/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def check_liquidity(): response = requests.get(f"{API_BASE}/interest", headers=headers) response.raise_for_status() for interest in response.json()["interest"]: if interest["liq_check_status"] == "CAN TRADE NOW": if interest["firmness"] == "Soft": print(f"ALERT: {interest['short_name']} ready to trade!") print(f" Livemid: {interest['livemid']}") print(f" Your limit: {interest['limit']}") print(f" Trade count (5d): {interest['tc5']}") # Poll every 30 seconds while True: check_liquidity() time.sleep(30)

8.3 WebSocket Integration

Real-time blotter monitoring:

PYTHON
import websocket import json import threading API_KEY = "ak_live_..." def on_message(ws, message): data = json.loads(message) if data["type"] == "interest_update": interest = data["data"] print(f"Update: {interest['short_name']} - {interest['liq_check_status']}") elif data["type"] == "trading_update": filled_mm = data['data']['qty_traded'] / 1_000_000 print(f"Trading: {data['data']['firmness_pres']} - filled {filled_mm}MM") def on_open(ws): # Authenticate ws.send(json.dumps({"type": "auth", "api_key": API_KEY})) # Start heartbeat thread def heartbeat(): while True: ws.send(json.dumps({"type": "heartbeat"})) time.sleep(25) threading.Thread(target=heartbeat, daemon=True).start() ws = websocket.WebSocketApp( "wss://api.ediphy.io/blotter/v1/stream", on_message=on_message, on_open=on_open ) ws.run_forever()

9. Rate Limiting

9.1 Default Limits

Endpoint Rate Limit
POST /interest 10/second
POST /interest/batch 1/second
POST /interest/remove 10/second
POST /interest/clear-all 1/minute
POST /interest/{id}/go-firm 5/second
GET /interest 10/second
GET /interest/team 5/second
GET /interest/latest 20/second
GET /audit 5/second

Need higher limits? Contact support@ediphymarkets.com to discuss increased rate limits for high-volume use cases.

9.2 Response Headers

X-Ediphy-RateLimit-Limit: 10
X-Ediphy-RateLimit-Remaining: 8
X-Ediphy-RateLimit-Reset: 2025-01-15T10:31:00Z

9.3 Rate Limit Exceeded (429)

JSON
{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests", "retry_after": 5 } }

10. Security Considerations

10.1 Transport Security

10.2 Data Isolation

10.3 Concurrency Model

The Liquidity Checker uses a last-write-wins concurrency model. When multiple users or systems update the same interest record simultaneously, the most recent write takes precedence.

Note

For team blotters with high concurrency, coordinate updates via client_id prefixes or establish conventions for which systems own which records.

10.4 Audit Trail

All API requests are logged with:

Query Audit Log

GET /audit

Query the audit trail for interest changes. Useful for compliance, debugging, and understanding change history.

Query Parameters
Parameter Description
interest_id Filter by specific interest record
client_id Filter by client reference ID
inst_id Filter by ISIN
user Filter by user who made the change
from Start of time range (ISO8601)
to End of time range (ISO8601)
limit Max results (default 100, max 1000)
cursor Pagination cursor
Response (Success - 200 OK)
JSON
{ "audit_entries": [ { "entry_id": "audit_abc123", "timestamp": "2025-01-15T10:32:15.789Z", "user": "jsmith", "action": "update", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "client_id": "my-order-001", "inst_id": "US912828ZT77", "changes": { "limit": { "old": 99.50, "new": 99.75 }, "prov": { "old": "sync", "new": "gui" } }, "source": "api", "request_id": "req_xyz789" }, { "entry_id": "audit_def456", "timestamp": "2025-01-15T10:30:00.123Z", "user": "oms_service", "action": "create", "interest_id": "INTEREST_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "client_id": "my-order-001", "inst_id": "US912828ZT77", "changes": { "qty": { "old": null, "new": 5000000 }, "verb": { "old": null, "new": "buy" }, "limit": { "old": null, "new": 99.50 } }, "source": "batch", "request_id": "req_batch_001" } ], "pagination": { "total": 2, "limit": 100, "has_more": false } }
Audit Entry Fields
Field Description
entry_id Unique audit entry identifier
timestamp When the change occurred
user User or service account that made the change
action Type of change: create, update, remove, go_firm
interest_id Affected interest record
client_id Client reference ID
inst_id ISIN
changes Object showing old and new values for each changed field
source Origin of change: api, batch, gui, system
request_id Associated API request ID (for tracing)

11. Endpoint Summary

Method Endpoint Description
POST /interest Add or update interest
POST /interest/remove Remove interest
POST /interest/clear-all Clear all interest
POST /interest/batch Batch upload
POST /interest/{id}/go-firm Transition interest to firm order
GET /interest List user's interest
GET /interest/team List team's interest
GET /interest/latest Get recent changes
GET /audit Query audit trail
WSS /stream WebSocket for real-time updates

12. Appendix: Field Reference

12.1 Interest Request Fields

Field Type Required Description
inst_id string Yes ISIN (12 characters)
client_id string No Client reference ID (max 64 chars)
verb string No "buy", "sell", or null
qty integer No Quantity in base currency units
limit number No Price limit
firmness string No "Soft", "Inactive"
comment string No Free-form note
status string No "Active" (default), "Inactive"

12.2 Interest Response Fields

Core Interest Fields:

Field Type Description
interest_id string System-generated unique ID
client_id string Client reference ID
inst_id string ISIN
verb string "buy", "sell", or null
qty number Quantity in base currency units
limit number Price limit
firmness string Raw firmness state
firmness_pres string Presentation firmness (accounts for trading state)
comment string User-provided note
prov string Provenance ("sync", "gui")
owner_user string Owner username
originator_user string User who created the interest
ts_captured string Last update timestamp

Reference Data Fields:

Field Type Description
short_name string Bond short name (e.g., "T 2.5 05/15/30")
legal_name string Issuer legal name
coupon number Coupon rate
currency_rd string Currency code
maturity string Maturity date (ISO format)

MiFID Post-Trade Data:

Field Type Description
notional_amount_usd number Total traded volume (USD) in last 60 days
count integer Total trade count in last 60 days
med_y number Median traded yield from recent transactions
fairmark_price number Ediphy dynamic end-of-day mark price
fairmark_date string Date of the most recent mark

Liquidity Score Fields:

Field Type Description
liq_check_status string Composite liquidity indicator
tc5 integer Trade count in last 5 days
tc20 integer Trade count in last 20 days
lb5 integer Days lookback to find 5 trades
lb20 integer Days lookback to find 20 trades
lb50 integer Days lookback to find 50 trades
lb1mm integer Days lookback to find 1MM USD volume
lb10mm integer Days lookback to find 10MM USD volume
lb50mm integer Days lookback to find 50MM USD volume
alt_count integer Number of liquid alternative instruments

Live Market Data:

Field Type Description
livemid number Current live mid-price (when available)
flags_tradable boolean Whether tradable on Ediphy

Trading Status Fields:

Field Type Description
ticket_id string Active trading ticket ID (if firm)
qty_traded number Total quantity filled (base currency units)
ticket_count integer Number of tickets created
trading_limit number Limit on active ticket
trading_mkt_quantity number Quantity working in market
trading_status string Trading ticket status
trading_user string User who owns firm order
actions string Available action: "Go Firm", "Update Firm"