Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion account/plan-limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ All plans are subject to a maximum of 50 simultaneous requests at any given time

## Historical Data Age Limit

The Free Forever and Starter plans include historical age limits on historical data queries. If you attempt to access data older than the plan's limits permit, the request will be denied.
Free Forever accounts can access up to 1 year of historical data and Starter accounts can access up to 5 years. Trader, Quant, and Prime plans have no historical data age limit. If you request data older than your plan allows, the request will be denied.

## Data Type

Expand Down
61 changes: 61 additions & 0 deletions api/cors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: CORS
sidebar_position: 4
---

The Market Data API includes **Cross-Origin Resource Sharing (CORS)** headers as a convenience for subscribers who want to make API requests directly from a browser during development or for personal use. CORS support is not an invitation to build public-facing applications — self-service plans are personal licenses and [data redistribution](/docs/account/data-policies/data-redistribution) is not permitted.

## Permitted Use Cases

CORS is intended for **personal, non-public use** of the API in a browser environment. Examples of permitted use:

- **Local development and prototyping** — building and testing apps on `localhost`.
- **Personal dashboards and tools** — browser-based apps that only you access.

These use cases are consistent with your self-service plan's personal license. The data you retrieve is for your own consumption — you are not making it available to others.

## What Is Not Permitted

Using CORS to serve market data to other people is **redistribution**, regardless of whether your app is free or paid. This includes:

- Public websites or apps that display market data to visitors
- Browser-based products or services that expose Market Data's data to your users or customers
- Shared dashboards or tools accessible to people outside your organization

These use cases require a commercial redistribution license. See the [Data Redistribution Policy](/docs/account/data-policies/data-redistribution) for details, or [contact our sales team](https://www.marketdata.app/contact/) to discuss licensing.

## CORS Headers

The API returns the following CORS headers on all responses, including preflight (`OPTIONS`) requests:

| Header | Value |
|--------------------------------|----------------------------------------------------------------------------------------------------------------|
| `Access-Control-Allow-Origin` | `*` |
| `Access-Control-Allow-Methods` | `DELETE, GET, OPTIONS, PATCH, POST, PUT` |
| `Access-Control-Allow-Headers` | `accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with` |
| `Access-Control-Max-Age` | `86400` (24 hours) |

## Token Security

When you use the API from a browser, your token is included in client-side code that **anyone with access to the page can inspect**. Only use your token in browser environments where you control who has access.

:::danger Never Expose Your Token on a Public Website
Do not embed your API token in any website, page, or app that is accessible to the public internet without authentication. Anyone who visits the page can extract your token from the network requests or source code and use it to make requests on your account, consuming your credits and accessing your data.

If your token is compromised, contact our helpdesk via the [customer dashboard](https://www.marketdata.app/dashboard/) immediately to have it revoked and reissued.
:::

## Example

The following example is suitable for local development or a personal/internal app:

```javascript
const response = await fetch("https://api.marketdata.app/v1/stocks/quotes/AAPL/", {
headers: {
Authorization: "Bearer YOUR_TOKEN",
},
});

const data = await response.json();
console.log(data);
```
34 changes: 33 additions & 1 deletion api/dates-and-times.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
---
title: Dates and Times
sidebar_position: 5
sidebar_position: 6
---

## Response Timestamps

By default, all timestamps returned by the API are **Unix timestamps** (seconds since January 1, 1970 UTC). You can change the output format using the [`dateformat`](/docs/api/universal-parameters/date-format) universal parameter, which supports `unix` (default), `timestamp` (ISO 8601 with timezone), and `spreadsheet` formats. Refer to individual endpoint documentation for details on how timestamps are set for each response type.

## Response Timezone

:::info All Timestamps Use Eastern Time
All US market timestamps returned by the Market Data API are anchored to the **America/New_York** timezone (US Eastern Time). This applies to **all asset classes**, including equities and options. Even though many US-listed options trade on Chicago exchanges, the API normalizes all US timestamps to Eastern Time. The API automatically adjusts for **daylight saving time** (EST/EDT).
:::

During Eastern Standard Time (EST, UTC-5), midnight Eastern is 05:00 UTC. During Eastern Daylight Time (EDT, UTC-4), midnight Eastern is 04:00 UTC. You do not need to handle this offset yourself — simply parse all timestamps using the `America/New_York` timezone identifier and your date library will resolve the correct date.

### Date-Based Timestamps

For responses that represent a **calendar date** rather than a specific moment in time — such as daily stock candles — the Unix timestamp is set to **midnight Eastern Time (00:00 America/New_York)** on the relevant date.

For example, a daily candle for **March 6, 2026** has Unix timestamp `1772773200`, which equals **05:00 UTC** (= 00:00 Eastern during EST). The 05:00 UTC value does not represent a market event — it is simply midnight Eastern expressed as a UTC-based Unix timestamp. The date portion (March 6) identifies the trading session.

:::caution Common Mistake
If you parse a daily timestamp as UTC instead of Eastern Time, the date may appear shifted. For example, Unix timestamp `1772773200` is `2026-03-06 05:00:00 UTC` but `2026-03-06 00:00:00 America/New_York`. If your code extracts the date using UTC, it will produce the correct result in this case, but during EDT the offset changes to 04:00 UTC and edge cases can cause the date to shift by a day. Always use `America/New_York` when extracting dates from these timestamps.
:::

:::tip SDK Users
If you use an official [Market Data SDK](/docs/sdk), timezone handling is done for you automatically. The SDKs convert all API timestamps to proper date and time objects in America/New_York — for example, Carbon in PHP, datetime in Python, and time.Time in Go — so you don't need to manage timezone conversion yourself.
:::

### Real-Time and Intraday Timestamps

For real-time quotes, intraday candles, and `updated` fields, the timestamp represents the actual moment the data was captured or last refreshed. These are standard Unix timestamps and can be converted to any timezone, but they correspond to Eastern Time market hours (regular session 9:30 AM – 4:00 PM ET).

### Options Timestamps

Although US-listed options primarily trade on exchanges in Chicago (CBOE), the API returns all option timestamps in **Eastern Time**, consistent with the rest of the API. The `updated` field on option quotes and chain responses reflects the Eastern Time snapshot of the data.

Option expiration timestamps reflect the **actual expiration time**, not midnight. Equity options expire at **4:00 PM Eastern** and index options expire at **4:15 PM Eastern**.

## Request Date Formats

All Market Data endpoints support advanced date-handling features to allow you to work with dates in a way that works best for your application. Our API will accept date inputs in any of the following formats:
Expand Down
2 changes: 1 addition & 1 deletion api/funds/candles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ echo $candles;

- **t** `array[number]`

Candle time (Unix timestamp). This is midnight US Eastern Time on the session date (e.g., 05:00 UTC during EST or 04:00 UTC during EDT).
Candle time. This is midnight US Eastern Time on the session date. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
4 changes: 2 additions & 2 deletions api/options/chain.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ The `am` and `pm` parameters are only applicable for index options such as SPX,

- **expiration** `array[number]`

The option's expiration date in Unix time.
The option's expiration date and time. Equity options expire at 4:00 PM Eastern and index options expire at 4:15 PM Eastern. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

- **side** `array[string]`

Expand Down Expand Up @@ -377,7 +377,7 @@ The `am` and `pm` parameters are only applicable for index options such as SPX,

- **updated** `array[number]`

The date and time of this quote snapshot in Unix time.
The date and time of this quote snapshot. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

- **iv** `array[number]`

Expand Down
2 changes: 1 addition & 1 deletion api/options/expirations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ echo $expirations;

- **updated** `date`

The date and time of this list of options strikes was updated in Unix time. For historical strikes, this number should match the `date` parameter.
The date and time of this list of options expirations was last updated. All timestamps use US Eastern Time (America/New_York). For historical expirations, this should match the `date` parameter. See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
2 changes: 1 addition & 1 deletion api/options/quotes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ echo $quotes;

- **updated** `array[number]`

The date and time of this quote snapshot in Unix time.
The date and time of this quote snapshot. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

- **iv** `array[number]`

Expand Down
2 changes: 1 addition & 1 deletion api/options/strikes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ echo $strikes;

- **updated** `array[number]`

The date and time of this list of options strikes was updated in Unix time. For historical strikes, this number should match the `date` parameter.
The date and time of this list of options strikes was last updated. All timestamps use US Eastern Time (America/New_York). For historical strikes, this should match the `date` parameter. See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
2 changes: 1 addition & 1 deletion api/rate-limiting.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Rate Limits
sidebar_position: 4
sidebar_position: 5
---

We enforce rate limits to ensure our API remains accessible and efficient for all users. We have two types of limits: API credits (total credits per unit of time) and a concurrent request limit (simultaneous requests).
Expand Down
2 changes: 1 addition & 1 deletion api/stocks/bulkcandles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ echo $candles;

- **t** `array[number]`

Candle time (Unix timestamp). This is midnight US Eastern Time on the session date (e.g., 05:00 UTC during EST or 04:00 UTC during EDT).
Candle time. This is midnight US Eastern Time on the session date. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
6 changes: 1 addition & 5 deletions api/stocks/candles.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,7 @@ There is no maximum date range limit on daily candles. When requesting intraday

- **t** `array[number]`

Candle time (Unix timestamp). For intraday candles, this is the candle's start time in UTC. For daily and longer resolutions, this is midnight US Eastern Time on the session date (e.g., 05:00 UTC during EST or 04:00 UTC during EDT).

:::tip Understanding Daily Candle Timestamps
A daily candle for **Friday, March 6, 2026** has Unix timestamp `1772773200`, which equals **05:00 UTC on March 6** (= 00:00 Eastern). The 05:00 UTC time does not represent a market event — it is simply midnight Eastern expressed in UTC. The date portion (March 6) identifies the trading session.
:::
Candle time. For intraday candles, this is the candle's start time. For daily and longer resolutions, this is midnight US Eastern Time on the session date. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
2 changes: 1 addition & 1 deletion api/stocks/prices.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ You can provide the symbol(s) in one of two ways:

- **updated** `array[date]`

Array of date/times for each stock price.
Array of date/times for each stock price. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
2 changes: 1 addition & 1 deletion api/stocks/quotes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ You can provide the symbol(s) in one of two ways:

- **updated** `array[date]`

The date/time of the current stock quote.
The date/time of the current stock quote. All timestamps use US Eastern Time (America/New_York). See [Response Timezone](/docs/api/dates-and-times#response-timezone) for details.

</TabItem>
<TabItem value="NoData" label="No Data">
Expand Down
14 changes: 7 additions & 7 deletions api/universal-parameters/date-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,30 @@ title: Date Format
sidebar_position: 3
---

The dateformat parameter allows you specify the format you wish to receive date and time information in.
The dateformat parameter allows you to specify the format you wish to receive date and time information in. Regardless of format, all timestamps for US markets use the **America/New_York** timezone. See [Response Timezone](/docs/api/dates-and-times#response-timezone) for full details on timezone handling.

## Parameter

dateformat=\<timestamp\|unix\|spreadsheet\>

## Use Example

/candles/daily/AAPL?dateformat=timestamp
/candles/D/AAPL/?dateformat=timestamp

/candles/daily/AAPL?dateformat=unix
/candles/D/AAPL/?dateformat=unix

/candles/daily/AAPL?dateformat=spreadsheet
/candles/D/AAPL/?dateformat=spreadsheet

## Values

### timestamp

Receive dates and times as a timestamp. Market Data will return time stamped data in the timezone of the exchange. For example, closing bell on Dec 30, 2020 for the NYSE would be: **2020-12-30 16:00:00 -05:00**.
Receive dates and times as an ISO 8601 timestamp with timezone offset. All US market data is returned in America/New_York. For example, closing bell on Dec 30, 2020 for the NYSE would be: **2020-12-30 16:00:00 -05:00**.

### unix

Receive dates and times in unix format (seconds after the unix epoch). Market Data will return unix date and time data. For example, closing bell on Dec 30, 2020 for the NYSE would be: **1609362000**.
Receive dates and times in unix format (seconds after the unix epoch). For example, closing bell on Dec 30, 2020 for the NYSE would be: **1609362000**. Unix timestamps are anchored to America/New_York — see [Response Timezone](/docs/api/dates-and-times#response-timezone) for how to interpret them correctly.

### spreadsheet

Receive dates and times in spreadsheet format (days after the Excel epoch). For example, closing bell on Dec 30, 2020 for the NYSE would be: **44195.66667**. Spreadsheet format does not support time zones. All times will be returned in the local timezone of the exchange.
Receive dates and times in spreadsheet format (days after the Excel epoch). For example, closing bell on Dec 30, 2020 for the NYSE would be: **44195.66667**. Spreadsheet format does not include a timezone offset. All times are expressed in America/New_York.
41 changes: 39 additions & 2 deletions sdk/sdk-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ unlisted: true

This document defines the requirements for official Market Data SDKs. Use this as acceptance criteria when building or evaluating SDK implementations.

## Core Principle: Language-Idiomatic Design
## Core Principles

### Language-Idiomatic Design

**SDKs must feel native to their language.** We adapt to the language's conventions—the language does not adapt to us.

Expand All @@ -22,6 +24,39 @@ This means:
- Don't force patterns from one language onto another
- **Follow official style guides and best practices for each language**

### Easy Default Requests

**Customers must be able to make a request and inspect the result in 2–3 lines of code.** Every endpoint must have a simple, zero-configuration path (beyond authentication) that returns a useful, printable result.

This means:
- Every endpoint method must work with just required parameters (e.g., a symbol) — no mandatory configuration or boilerplate
- Response objects must support string conversion that produces a readable summary (see §11.5)
- Environment-based token loading (`MARKETDATA_TOKEN`) must work automatically so users can skip explicit auth setup
- The combination of env-based auth + simple method call + print/log must produce a meaningful result

#### Examples

**Python (3 lines):**
```python
from marketdata import MarketDataClient
client = MarketDataClient()
print(client.stocks.quotes("AAPL"))
```

**Go (3 lines, excluding package/import):**
```go
client, _ := marketdata.NewClient()
quotes, _ := client.Stocks.Quotes("AAPL")
fmt.Println(quotes)
```

**PHP (3 lines):**
```php
$client = new MarketDataClient();
$quote = $client->stocks->quotes("AAPL");
echo $quote;
```

### Required Style Guides

| Language | Style Guide / Best Practices |
Expand Down Expand Up @@ -55,6 +90,7 @@ SDKs must pass the standard linter for their language (e.g., `ruff` for Python,

| Requirement | Priority |
|-----------------------------------|----------|
| Easy default requests (2–3 lines) | Must |
| Bearer token authentication | Must |
| Environment-based configuration | Must |
| Connection pooling | Must |
Expand Down Expand Up @@ -624,7 +660,7 @@ Integration tests make **actual REST requests** to the live API:
### README Must Include

- [ ] Installation instructions
- [ ] Quick start example (auth + first request)
- [ ] Quick start example showing a complete request in 2–3 lines of code
- [ ] Environment variable configuration
- [ ] Error handling example
- [ ] String conversion example(s) showing ergonomic object output
Expand Down Expand Up @@ -680,6 +716,7 @@ Integration tests make **actual REST requests** to the live API:
Before accepting an SDK, verify:

### Core Functionality
- [ ] Every endpoint works in 2–3 lines of code (env auth + method call + print)
- [ ] All required SDK method capabilities implemented (as defined in this doc and canonical API docs)
- [ ] Bearer authentication works
- [ ] Token validation defaults to startup (fail fast) and supports constructor override to disable startup validation
Expand Down
Loading