Making Your First Request

To interact with the Paper API, you'll need an API key which you can generate from the settings page of Paper's portal at app.paperinvest.io. Once you have your API key, you'll need to exchange it for a JWT token.

Base URL

All API requests should be made to:

https://api.paperinvest.io

All endpoints are prefixed with /v1, so a complete URL would look like:

https://api.paperinvest.io/v1/orders

Authentication

First, exchange your API key for a JWT token:

Get Token

POST
/v1/auth/token
curl -X POST https://api.paperinvest.io/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_API_KEY"
  }'

Token Response

JSON
200 OK
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "rf_2n8Kj3hGpQxM..."
}

All API requests must include the following headers:

Required Headers

HTTP
Headers
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json

Example Request

Here's an example of how to create an order using the Paper API:

Example Request

POST
/v1/orders
curl -X POST https://api.paperinvest.io/v1/orders \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "portfolioId": "550e8400-e29b-41d4-a716-446655440000",
    "symbol": "AAPL",
    "quantity": 100,
    "orderType": "MARKET",
    "positionIntent": "BUY_TO_OPEN",
    "timeInForce": "DAY",
    "assetClass": "EQUITY"
  }'

Example Response

JSON
200 OK
{
  "orderId": "123e4567-e89b-12d3-a456-426614174000",
  "portfolioId": "550e8400-e29b-41d4-a716-446655440000",
  "symbol": "AAPL",
  "quantity": 100,
  "orderType": "MARKET",
  "positionIntent": "BUY_TO_OPEN",
  "timeInForce": "DAY",
  "assetClass": "EQUITY",
  "status": "PENDING",
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}

Error Handling

All Paper API endpoints implement detailed validation and provide clear error messages. If your request fails, you'll receive an appropriate HTTP status code along with a JSON response containing error details.

Validation Error

JSON
400 Bad Request
{
  "message": "Validation failed",
  "errors": {
    "quantity": ["quantity must be a positive number"],
    "orderType": ["orderType must be one of: MARKET, LIMIT, STOP, STOP_LIMIT"],
    "timeInForce": ["timeInForce must be one of: DAY, GTC, IOC, FOK"]
  },
  "receivedValue": {
    "portfolioId": "550e8400-e29b-41d4-a716-446655440000",
    "symbol": "AAPL",
    "quantity": -10,
    "orderType": "INVALID",
    "timeInForce": "INVALID"
  }
}

Rate Limit Error

JSON
429 Too Many Requests
{
  "statusCode": 429,
  "message": "Rate limit exceeded",
  "limit": 200,
  "remaining": 0,
  "resetTime": 60
}

For more information on error handling, see the Status Codes section.