# Search posts

Live LinkedIn post search by keyword, hashtag, or author.

**POST** `https://api.up2data.ai/v1/search/posts`

**Credits:** 1 credit per page (up to 25 posts) - **Mode:** synchronous

Provide at least one of `keywords`, `hashtags`, `author_url`, or `author_urn`. Several keywords and hashtags match any of them. With an author, the search reads that profile's recent posts and applies `keywords`, `hashtags`, and `posted_within` to them; `sort: top` then orders by reactions. `share_urn` is the full URN (`urn:li:share:...` or `urn:li:ugcPost:...`); `media` is an extra field at the end of each post when it has images or video. `meta.reason` is `success`, or `empty_result` when nothing matched.

> **Info:** Counts as 1 request against the 300/min per-key limit and 1 search against the 20/hour per-organization search quota. See [Rate limits](https://up2data.ai/docs/v1/guides/rate-limits/).

> **Info:** Send many as batch operation items (operation search.posts); up to 500 posts per item, 1 credit per 25-row page. See the [batch endpoint](https://up2data.ai/docs/v1/api/batch-create/).

## Request

| Field | Type | Notes |
|---|---|---|
| `keywords` | `string[]` |  |
| `hashtags` | `string[]` | Without the leading #. |
| `author_url` | `string` | Profile URL or public identifier. Send author_url or author_urn, not both. |
| `author_urn` | `string` | Member URN (ACoAA...). |
| `posted_within` | `string` | Enum: 24h, week, month, all. Default all. |
| `sort` | `string` | Enum: recent, top, relevance. Default recent. |
| `max_results` | `integer` | Default 25. 1 to 100. |

## Call it

**cURL**

```bash
curl -X POST "https://api.up2data.ai/v1/search/posts" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "keywords": [
    "ai agents"
  ],
  "posted_within": "week",
  "sort": "recent",
  "max_results": 25
}'
```

**Python**

```python
import requests

url = "https://api.up2data.ai/v1/search/posts"
headers = {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
}
payload = {
    "keywords": [
        "ai agents"
    ],
    "posted_within": "week",
    "sort": "recent",
    "max_results": 25
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())
```

**Node**

```javascript
const url = "https://api.up2data.ai/v1/search/posts";
const headers = {
  "X-API-Key": "YOUR_API_KEY",
  "Content-Type": "application/json",
};
const body = {
  "keywords": [
    "ai agents"
  ],
  "posted_within": "week",
  "sort": "recent",
  "max_results": 25
};

const response = await fetch(url, {
  method: "POST",
  headers,
  body: JSON.stringify(body),
});
const data = await response.json();
console.log(data);
```

**Go**

```go
package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.up2data.ai/v1/search/posts"
	body := bytes.NewBufferString(`{
  "keywords": [
    "ai agents"
  ],
  "posted_within": "week",
  "sort": "recent",
  "max_results": 25
}`)
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	respBody, _ := io.ReadAll(resp.Body)
	fmt.Println(string(respBody))
}
```

## Response

**200**

```json
{
  "data": {
    "posts": [{ "url": "https://www.linkedin.com/posts/katykeim_gtm-teams-are-losing-track-of-their-ai-agents-activity-7509369170732507138-zjBG", "urn": "7509369170732507138", "share_urn": "urn:li:share:7509369169658908672", "author": { "name": "Katy Keim", "url": "https://www.linkedin.com/in/katykeim", "headline": "CEO, LeanData | CMO | Independent Board Member" }, "text": "MarTech's take on our latest LeanData research: What happens when your organization has so many agents at work that you start losing track of them?", "posted_at": "2026-09-25T21:49:51.000Z", "reactions_count": 0, "comments_count": 0, "reposts_count": 0, "scraped_at": "2026-09-25T21:52:56.000Z" }]
  },
  "meta": { "creditsUsed": 1, "creditsRemaining": 98418, "billed": true, "reason": "success", "requestId": "req_example", "latencyMs": 4700 }
}
```

## Errors

| Status | Type | When | Billed |
|---|---|---|---|
| 400 | `invalid_request` | None of keywords, hashtags, author_url, or author_urn, both author_url and author_urn, unknown field, or a bad enum value. | No |
| 401 | `invalid_api_key` | Missing, malformed, or revoked key. | No |
| 402 | `insufficient_credits` | Balance can't cover the page(s) requested. | No |
| 422 | `unprocessable_target` | The author profile is not found, private, or unreachable. Billed as 1 credit. | Yes |
| 429 | `rate_limited` | Over the 300 requests/min limit, or the 20 searches/hour per-organization quota. Honor Retry-After. | No |
| 500 | `upstream_error` | LinkedIn rejected the search query, or something broke on the server side. | No |
| 504 | `upstream_timeout` | The live scrape didn't complete in time. | No |

See the [Errors guide](https://up2data.ai/docs/v1/guides/errors/) for every error type this version can return.
