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:

  1. Navigate to Settings → API Keys in your workspace.
  2. Click Create key, choose a name (e.g. prod-signal-reader), and select the scopes you need.
  3. Copy the key — it is shown only once. Store it in a secret manager (AWS Secrets Manager, Vault, Doppler, etc.).
  4. 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

ScopeAccessEndpoints
signals:readRead-onlyGET /v1/signals
trades:readRead-onlyGET /v1/trades
reports:readRead-onlyGET /v1/reports, GET /v1/reports/trades
account:readRead-onlyGET /v1/me, GET /v1/account/usage
webhooks:writeWriteManage 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.

PlanAPI req / minWebhooks / minBurstNotes
Basic6010No burst headroom
Pro30060Short burst window (5 s)
Business1000200Burst up to 3 000 RPM for ≤ 5 s
EnterpriseCustomCustomCustomNegotiated SLA, custom concurrency

Response headers

Every API response includes rate-limit headers so your integration can stay within bounds without trial and error:

HeaderValue
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetISO 8601 timestamp when the window resets
Retry-AfterSeconds 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 statusMeaningAction
400Bad RequestFix the request body / query params
401UnauthorizedCheck key value and Authorization header format
403ForbiddenKey lacks the required scope for this endpoint
404Not FoundResource does not exist or was deleted
422UnprocessablePasses schema but business-rule validation failed
429Rate LimitedBack off and retry (see Retry-After)
5xxServer ErrorTransient — 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

ParamTypeRequiredDescription
sinceISO 8601NoReturn signals received at or after this time
limitnumberNoMax results per page (default 25, max 100)
pagenumberNoPage number (1-based)
instrumentstringNoFilter by instrument, e.g. EURUSD
statusstringNoFilter by status: parsed | pendinginvalid

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 ↗

ParamTypeRequiredDescription
sinceISO 8601NoOnly trades opened at or after this time
limitnumberNoMax results per page (default 25, max 100)
pagenumberNoPage number (1-based)
instrumentstringNoFilter by instrument
statusstringNoFilter by status: open | closedpending

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

EventWhenPayload type
signal.receivedA signal was parsed from any sourceSignalIntent
signal.parsedParser normalized the source messageParsedSignal
trade.openedA broker position was openedTradeOpened
trade.closedA broker position was closedTradeClosed
trade.tp_hitTake profit was hitTradeClosed
trade.sl_hitStop loss was hitTradeClosed
subscription.upgradedSubscription moved to a higher tierSubscription
subscription.canceledCancellation was scheduledSubscription

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 →