# Can I get X (Twitter) posts by date range?

X (Twitter). Checked September 2026.

Partly. The profile posts endpoint accepts `since`, an RFC 3339 timestamp, and stops paging once posts are older than it. That gives you "everything after a date" in one loop without paying for older pages. There is no `until`. For an end date, skip posts whose `createdAt` is past it.

Search has no date filter at all. It returns what X ranks for the query now. For a search bounded by time, run it on a schedule and keep the results. Your store becomes the range.

## GET /v1/twitter/profiles/@handle/posts?since=…

```bash
curl "https://api.openhandle.dev/v1/twitter/profiles/@copperfield_lab_x_test/posts?since=2026-08-01T00:00:00Z" \
  -H "Authorization: Bearer $OPENHANDLE_API_KEY"
```

```ts
import { OpenHandle } from '@openhandle/sdk';

const openhandle = new OpenHandle({ apiKey: process.env.OPENHANDLE_API_KEY! });
const start = '2026-08-01T00:00:00Z';
const end = new Date('2026-09-01T00:00:00Z');

let page = await openhandle.twitter.profile('copperfield_lab_x_test').posts.list({ since: start });
while (page) {
    for (const post of page.data) {
        if (new Date(post.createdAt) < end) console.log(post.createdAt, post.text);
    }
    page = await page.next();
}
```

200 OK:

```json
{
  "platform": "twitter",
  "resource": "post",
  "capturedAt": "2026-09-18T12:34:55Z",
  "source": "live",
  "data": [
    {
      "id": "940100000000000001",
      "text": "A deterministic text post from a fictional lab. #synthetic",
      "createdAt": "2026-08-09T15:30:00Z",
      "metrics": { "likes": 42, "reposts": 3, "comments": 3 }
    }
  ],
  "meta": { "cursors": { "next": null } }
}
```

Trimmed to one post. The cursor is null because every remaining post is older than `since`. The example is a Test account.

## What since does

- **Stops paging.** Once a page contains posts older than `since`, the cursor turns null. You do not pay for pages you would discard.
- **Newest first.** Feeds are ordered newest first. The first page is the most recent, the last page ends at your start date.
- **Works on every post feed.** Profile posts, replies, and media on X, and profile posts on Instagram, TikTok, and Reddit.

## What since does not do

- **No end date.** Filter `createdAt` on your side. A pinned post can appear at the top with an old date. Compare dates, do not assume order.
- **No search filter.** Search returns what X ranks now. `from:handle` and keywords narrow it. Dates do not.
- **No archive.** X decides how far back a public timeline goes. `since` cannot reach past that.

## Build the range yourself

Poll the feeds you care about with `since` set to the last `capturedAt` you stored. Every run appends only new posts. After a month you have a month. After a year you have a year, with the exact numbers each post showed on the day you read it.

## When this does not work

These answers are definitive. Store them, do not retry them.

| Situation | Status | Code |
|---|---|---|
| The account is protected | 403 | `PROFILE_PRIVATE` |
| The account is suspended, deleted, or never existed | 404 | `PROFILE_NOT_FOUND` |
| The since value is not an RFC 3339 timestamp | 400 | `INVALID_SINCE` |

```json
{
  "error": {
    "code": "INVALID_SINCE",
    "message": "The since value is invalid.",
    "requestId": "req_01j8…",
    "retryable": false
  }
}
```

Validation errors are never billed. Send timestamps in UTC with the Z suffix.

## Related

- [Pagination](https://openhandle.dev/docs/concepts/pagination): Opaque cursors, one page per request, and the since parameter.
- [How do I get all posts from an X user past 3,200?](https://openhandle.dev/questions/how-do-i-get-all-posts-from-an-x-user-past-3200): Paging a whole timeline and reaching older posts with search.
- [How do I search X (Twitter) posts by keyword?](https://openhandle.dev/questions/how-do-i-search-x-twitter-posts-by-keyword): Latest or top posts for any query.
