PipSync
Connectez Claude ou ChatGPT à votre compte de trading en direct — consultez les cotations et les positions, et passez, modifiez ou fermez des transactions avec une confirmation en deux étapes (uniquement dans le cadre du trading, jamais de retraits).
Documentation
Home›Developers›API Reference
v1 API · OpenAPI 3.1 · signed webhooks
An API built for traders who code.
REST where it makes sense, signed webhooks where events need to reach your systems. OpenAPI 3.1 spec, verifiable signatures, and copy-paste examples for every hot endpoint.
Interactive PlaygroundDownload OpenAPI spec
Getting started
QuickstartAuthenticationObtaining an API keyKey scopesKey security
Rate limits
Limits by tierResponse headersExponential backoff
Errors
Error codes
Endpoints
GET/v1/meGET/v1/signalsGET/v1/tradesGET/v1/reports
Webhooks
Realtime SSE streamEvent catalogueVerifying signatures
OpenAPI clients
Code generatorsInteractive Playground ↗
Quickstart
Store your key, call /v1/me to verify auth, then start reading signals or trades. Five minutes from zero to first API response.
cURLNode.jsPython
curl https://app.pipsync.io/api/v1/me
-H "Authorization: Bearer $PIPSYNC_KEY"
Every response is wrapped in { "data": … }. Paginated endpoints additionally return a "meta" object with total, page, totalPages, and hasMore.
Authentication
All API requests require a bearer token in the Authorization header. Keys are per-environment (live / sandbox), per-scope, and time-limited only if you choose to set an expiry.
HeaderAuthorization: Bearer pipsync_live_<32 alnum chars>
Obtaining an API key
API access requires the Enterprise plan. Once on Enterprise:
- Navigate to Settings → API Keys in your workspace.
- Click Create key, choose a name (e.g. prod-signal-reader), and select the scopes you need.
- Copy the key — it is shown only once. Store it in a secret manager (AWS Secrets Manager, Vault, Doppler, etc.).
- To rotate: create a replacement key, cut traffic over, revoke the old key. There is no downtime if you overlap by one deployment cycle.
Key scopes
| Scope | Access | Endpoints |
|---|---|---|
| signals:read | Read-only | GET /v1/signals |
| trades:read | Read-only | GET /v1/trades |
| reports:read | Read-only | GET /v1/reports, GET /v1/reports/trades |
| account:read | Read-only | GET /v1/me, GET /v1/account/usage |
| webhooks:write | Write | Manage webhook subscriptions (dashboard only) |
Key security
⚠
Never expose a live key in client-side code. Keys embedded in browser bundles, mobile apps, or public repos are compromised. Use sandbox keys for prototyping. Revoke a leaked key immediately from Settings → API Keys and create a replacement.
Additional hardening available on Enterprise: IP allowlist (restrict which CIDR ranges may use a key) and IP blocklist. Both configured per-key from the same settings page.
Rate limits
Limits are per API key per rolling 60-second window. Webhooks are separately rate-limited on their inbound delivery surface.
| Plan | API req / min | Webhooks / min | Burst | Notes |
|---|---|---|---|---|
| Basic | 60 | 10 | 1× | No burst headroom |
| Pro | 300 | 60 | 2× | Short burst window (5 s) |
| Business | 1000 | 200 | 3× | Burst up to 3 000 RPM for ≤ 5 s |
| Enterprise | Custom | Custom | Custom | Negotiated SLA, custom concurrency |
Response headers
Every API response includes rate-limit headers so your integration can stay within bounds without trial and error:
| Header | Value |
|---|---|
| X-RateLimit-Limit | Maximum requests allowed in the current window |
| X-RateLimit-Remaining | Requests remaining in the current window |
| X-RateLimit-Reset | ISO 8601 timestamp when the window resets |
| Retry-After | Seconds to wait before retrying (only on 429) |
ℹ
429 responses are retryable. Always read Retry-After and honour it. Do not hard-code a sleep duration — the exact window depends on your plan and current load.
Exponential backoff
Implement jittered exponential backoff whenever you receive a 429. This pattern prevents thundering-herd issues if your fleet is calling in parallel:
Node.jsPython
async function fetchWithRetry(url, key, maxRetries = 4) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, {
headers: { Authorization: Bearer ${key} },
});
if (res.status !== 429) return res.json();
const retryAfter = parseInt(res.headers.get("Retry-After") ?? "1", 10);
const backoff = retryAfter * 1000 * Math.pow(2, attempt) + Math.random() * 200;
await new Promise(r => setTimeout(r, backoff));
} throw new Error("Rate limit retries exhausted"); }
Error codes
All errors use RFC 7807 Problem Details (application/problem+json):
401 Unauthorized
{ "type": "https://app.pipsync.io/errors/unauthorized", "title": "Unauthorized", "status": 401, "detail": "Missing or invalid API key" }
| HTTP status | Meaning | Action |
|---|---|---|
| 400 | Bad Request | Fix the request body / query params |
| 401 | Unauthorized | Check key value and Authorization header format |
| 403 | Forbidden | Key lacks the required scope for this endpoint |
| 404 | Not Found | Resource does not exist or was deleted |
| 422 | Unprocessable | Passes schema but business-rule validation failed |
| 429 | Rate Limited | Back off and retry (see Retry-After) |
| 5xx | Server Error | Transient — retry with backoff; check pipsync.io/status |
GET /v1/me
Returns the profile of the workspace owner associated with the API key.
GET/v1/meTry it ↗
GET /v1/signals
Returns parsed trading signals for the workspace. Signals are the normalized output of the parser — ready for downstream processing.
GET/v1/signalsTry it ↗
Query parameters
| Param | Type | Required | Description | |
|---|---|---|---|---|
| since | ISO 8601 | No | Return signals received at or after this time | |
| limit | number | No | Max results per page (default 25, max 100) | |
| page | number | No | Page number (1-based) | |
| instrument | string | No | Filter by instrument, e.g. EURUSD | |
| status | string | No | Filter by status: parsed | pending | invalid |
curl "https://app.pipsync.io/api/v1/signals?limit=10"
-H "Authorization: Bearer $PIPSYNC_KEY"
GET /v1/trades
Returns trade records (opened, closed, partially-closed positions) for the workspace. Paginated; newest trades first.
GET/v1/tradesTry it ↗
| Param | Type | Required | Description | |
|---|---|---|---|---|
| since | ISO 8601 | No | Only trades opened at or after this time | |
| limit | number | No | Max results per page (default 25, max 100) | |
| page | number | No | Page number (1-based) | |
| instrument | string | No | Filter by instrument | |
| status | string | No | Filter by status: open | closed | pending |
curl "https://app.pipsync.io/api/v1/trades?limit=25"
-H "Authorization: Bearer $PIPSYNC_KEY"
GET /v1/reports
Enumerate generated trade reports and download links. Use /v1/reports/trades to get the detailed line-item CSV/PDF export.
GET/v1/reportsTry it ↗
✦
The full OpenAPI 3.1 spec (with request / response schemas for every endpoint) is available at /api/v1/openapi.json. Import it into Postman, Insomnia, or use the interactive playground to try every endpoint live.
Realtime stream
For browser dashboards and live monitoring, subscribe to /api/trading/stream with EventSource. This is the shipped SSE fallback when WebSocket upgrades are unavailable; keep signed webhooks for server-to-server automation.
Webhooks
Subscribe to push events from Settings → Webhooks. PipSync POSTs a signed JSON payload to your endpoint every time an event occurs. Delivery is attempted up to 5 times with exponential backoff.
POSTyour-server.com/pipsync — signed by X-PipSync-Signature
| Event | When | Payload type |
|---|---|---|
| signal.received | A signal was parsed from any source | SignalIntent |
| signal.parsed | Parser normalized the source message | ParsedSignal |
| trade.opened | A broker position was opened | TradeOpened |
| trade.closed | A broker position was closed | TradeClosed |
| trade.tp_hit | Take profit was hit | TradeClosed |
| trade.sl_hit | Stop loss was hit | TradeClosed |
| subscription.upgraded | Subscription moved to a higher tier | Subscription |
| subscription.canceled | Cancellation was scheduled | Subscription |
Verifying signatures
Every webhook delivery includes an X-PipSync-Signature header formatted as t=<unix-ts>,v1=<hex-hmac-sha256>. Verify before trusting the payload:
Node.jsPython
import crypto from "crypto";
export function verifyWebhook(rawBody: string, header: string, secret: string): boolean { const parts = Object.fromEntries( header.split(",").map((part) => part.split("=")), ); const signed = parts.t + "." + rawBody; const expected = crypto .createHmac("sha256", secret) .update(signed) .digest("hex"); // Constant-time comparison to prevent timing attacks return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(parts.v1 ?? ""), ); }
⚡
Always verify the timestamp. Reject payloads where t is more than 5 minutes in the past — this prevents replay attacks. Compare Math.abs(Date.now() / 1000 - Number(parts.t)) > 300.
OpenAPI clients
The shipped contract is the OpenAPI 3.1 spec at /api/v1/openapi.json. Generate a typed client in your runtime — or use the interactive playground for ad-hoc requests.
TypeScript
Generate with openapi-typescript
/api/v1/openapi.json
Python
Generate with openapi-python-client
Go
Generate with oapi-codegen
Rust
Generate with progenitor or openapi-generator
C#
Generate with NSwag
MQL5
Use REST + signed webhook examples
Contact us for EA samples
✦
Prefer the interactive playground for ad-hoc testing with your real key. Open Playground →