Skip to main content

API documentation

Bitcointalk data, ready for code.

Use stable HTTPS endpoints, Bearer authentication, and predictable JSON responses. The reference below is generated from the same contract as the downloadable OpenAPI 3.1 schema.

Quickstart

  1. 1

    Create an account

    Register, then open the developer dashboard.

  2. 2

    Create and fund a key

    Copy the key once and add prepaid crypto credit.

  3. 3

    Send a request

    Search the corpus or retrieve a post, topic, or profile by ID.

Authentication

Send your API key in the Authorization header. Keys begin with ts_live_, are displayed once, and can be revoked immediately from your dashboard.

Authorization: Bearer ts_live_your_key

The X-API-Key header is also supported. Never put a secret key in browser-delivered application code or a public repository.

Optional IP restrictions

Each key can be limited to individual IPv4 or IPv6 addresses and CIDR ranges, such as 203.0.113.10, 198.51.100.0/24, or 2001:db8::/32. Manage the allowlist from the developer dashboard. Requests from other addresses receive HTTP 403 before billing, with sourceIp showing the address TalkSearch detected.

Key expiration

Choose no expiration or a lifetime of 7, 30, 90, 180, or 365 days. An expired key receives HTTP 401 before billing. You can renew an expired key or change its expiration from the dashboard without replacing the secret.

Retrieve corpus resources by ID

Use the numeric IDs from Bitcointalk URLs or TalkSearch results. A missing resource returns HTTP 404 and costs no credit.

GET

Post by ID

/api/v1/posts/{id}

Returns one indexed post with rendered HTML, author, board, topic, date, and merit observations.

Example ID: 34538660

GET

Topic by ID

/api/v1/topics/{id}

Returns topic metadata plus the complete first post and a summary of the latest indexed post.

Example ID: 3309245

GET

Profile by ID

/api/v1/profiles/{id}

Returns corpus-derived profile activity and recent posts for a Bitcointalk user ID.

Example ID: 1978649

Page through topic or profile posts

Use these collection endpoints to retrieve full posts in chronological order. They read the indexed corpus, not a new web scrape, and do not apply relevance, language, spam or diversity filtering. You do not need to guess or walk post IDs.

Posts in a topic

GET /api/v1/topics/{id}/posts

Chronologically page through full indexed posts in a topic, optionally restricted to one author.

Posts by a profile

GET /api/v1/profiles/{id}/posts

Chronologically page through full indexed posts by an author, optionally restricted to one topic.

Snapshot consistency: the first request freezes a point-in-time view. Legacy duplicates are resolved to one deterministic canonical document per post, independently of the current filters. New posts and updates appear only when you start a new request without a cursor. No exact or approximate total is returned.

Continuation: send the returned next_cursor unchanged. A cursor-only request inherits the initial filters, order and limit. You may repeat identical options, but changed, empty, repeated or unknown options are rejected with HTTP 400.

Do not stop on an empty page: a bounded duplicate scan may return fewer posts, or no posts, with a continuation. Keep going until next_cursor is null. A topic or profile with no indexed posts returns HTTP 200 with an empty list.

Expiry: cursors expire after five idle minutes and the snapshot lasts at most one hour. HTTP 410 means start a new snapshot; a tampered or mismatched cursor returns 400. These errors and upstream failures are not charged. Each successful page, including an empty terminal page, costs one credit.

Collection query parameters
NameTypeDescription
limitintegerMaximum full posts per page (default 50). A bounded duplicate scan can return fewer or zero posts while next_cursor is still present.
orderstringChronological order; asc (oldest first) is the default. Ties use a stable post-ID order.
date_fromstringInclusive posting-time boundary. Exact YYYY-MM-DD means UTC midnight; alternatively use RFC3339 with an explicit timezone and at most millisecond precision.
date_tostringExclusive posting-time boundary, using the same date syntax. For all of September 9 UTC, use date_from=2026-09-09 and date_to=2026-09-10.
board_idintegerRestrict to one Bitcointalk board ID; supported on both collection endpoints.
author_uidintegerTopic posts only: restrict the topic to one author’s numeric Bitcointalk user ID.
topic_idintegerProfile posts only: restrict the author’s posts to one topic ID.
cursorstringOpaque signed continuation token from next_cursor. Send it unchanged. Cursor-only requests inherit the original filters, order and limit; explicitly repeated options must be identical. Never construct a cursor or increment post IDs.

Dates must be exact YYYY-MM-DD (UTC midnight) or RFC3339 timestamps with a timezone and no more than three fractional-second digits. date_from is inclusive; date_to is exclusive. Scope and filter IDs must be positive safe integers.

Python: topic posts from September 9, 2026, oldest first
import os
import requests

endpoint = "https://talksearch.io/api/v1/topics/5480200/posts"
headers = {"Authorization": "Bearer " + os.environ["TALKSEARCH_API_KEY"]}
params = {"date_from": "2026-09-09", "order": "asc", "limit": 50}

while True:
    response = requests.get(endpoint, headers=headers, params=params, timeout=60)
    response.raise_for_status()  # 410: explicitly start a new snapshot if needed
    page = response.json()
    for post in page["data"]:
        print(post["post_id"], post["posted_at"], post["content_html"])
    cursor = page["next_cursor"]
    if cursor is None:
        break
    # A short or empty page can still have a continuation. Do not increment IDs.
    params = {"cursor": cursor}  # Inherits all initial options; one credit/page.

Post-search parameters

NameTypeRequiredDescription
qstringYesSearch query. Must contain between 1 and 512 characters.
langstringNoLanguage index to search, such as en, de, fr, or pt-BR.
freshnessstringNoSet to 1 to prefer newer posts. Omit it to use automatic freshness intent detection.
include_low_qualitystringNoSet to 1 to include replies normally removed by TalkSearch quality and spam filtering.

Request examples

Use an environment variable or server-side secret manager for production keys.

curl 'https://talksearch.io/api/v1/search?q=taproot+fee+estimation&lang=en' \
  -H 'Authorization: Bearer ts_live_your_key'

Successful responses

Every response identifies its resource shape. The OpenAPI schema contains complete field definitions for code generation and validation.

Post search response
{
  "query": "taproot fee estimation",
  "corrected_query": null,
  "lang": "en",
  "board_scope": "strict-language-boards-v1",
  "index": "talksearch_posts_v3_en",
  "did_you_mean": null,
  "hybrid": true,
  "freshness": false,
  "answer_seeking": true,
  "total": 127,
  "hits": [
    {
      "post_id": 64551288,
      "topic_id": 5500892,
      "title": "When Taproot?",
      "topic_title": "When Taproot?",
      "post_title": "Re: When Taproot?",
      "content": "Example matching Bitcointalk post content.",
      "author": "ExampleUser",
      "author_uid": 3534730,
      "date": "2024-09-20T01:58:23.000Z",
      "board_id": 1,
      "board_name": "Bitcoin Discussion",
      "lang": "en",
      "score": 0.822709,
      "spam_score": 0,
      "ai_score": 0,
      "health_score": 1,
      "rank_source": "hybrid",
      "ranking_model_version": "relevance-authority-v5",
      "search_index": "talksearch_posts_v3_en"
    }
  ]
}
Image search response
{
  "object": "image_search",
  "query": "hardware wallet",
  "corrected_query": null,
  "lang": "en",
  "board_scope": "strict-language-boards-v1",
  "hide_nsfw": true,
  "post_matches_considered": 50,
  "total": 1,
  "images": [
    {
      "object": "image",
      "sha256": "53e2d1c2be8f2a0c87efbd85c73915b58344fd9a7f40b6eeb734f4014b5d0f07",
      "url": "https://cdn.talksearch.io/media/images/53e2d1c2be8f2a0c87efbd85c73915b58344fd9a7f40b6eeb734f4014b5d0f07.avif",
      "mime_type": "image/avif",
      "bytes": 48231,
      "nsfw_score": 0.01,
      "post": {
        "post_id": 64551288,
        "topic_id": 5500892,
        "title": "Hardware wallet comparison",
        "author": {
          "profile_id": 3534730,
          "username": "ExampleUser",
          "url": "https://bitcointalk.org/index.php?action=profile;u=3534730"
        },
        "board": {
          "board_id": 37,
          "name": "Hardware Wallets"
        },
        "language": "en",
        "posted_at": "2024-09-20T01:58:23.000Z",
        "url": "https://bitcointalk.org/index.php?topic=5500892.msg64551288#msg64551288",
        "topic_url": "https://bitcointalk.org/index.php?topic=5500892.0"
      }
    }
  ]
}
Post by ID response
{
  "object": "post",
  "post_id": 34538660,
  "topic_id": 3309245,
  "post_number": 1,
  "is_op": true,
  "title": "Forget about exchanger search! Use BestChange!",
  "author": {
    "profile_id": 1978649,
    "username": "Best.Change",
    "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
  },
  "board": {
    "board_id": 84,
    "name": "Service Announcements"
  },
  "language": "en",
  "posted_at": "2018-04-12T00:00:00.000Z",
  "url": "https://bitcointalk.org/index.php?topic=3309245.msg34538660#msg34538660",
  "topic_url": "https://bitcointalk.org/index.php?topic=3309245.0",
  "content_html": "<p>BestChange.com helps compare exchangers.</p>",
  "indexed_at": "2026-08-29T12:00:00.000Z",
  "merit": {
    "total": 0,
    "distinct_senders": 0,
    "transactions": 0,
    "observed_at": null
  }
}
Topic by ID response
{
  "object": "topic",
  "topic_id": 3309245,
  "title": "Forget about exchanger search! Use BestChange!",
  "board": {
    "board_id": 84,
    "name": "Service Announcements"
  },
  "language": "en",
  "created_at": "2018-04-12T00:00:00.000Z",
  "last_post_at": "2026-08-29T00:00:00.000Z",
  "post_count": 2400,
  "page_count": 120,
  "views": {
    "observed": 100000,
    "observed_at": "2026-08-29T00:00:00.000Z"
  },
  "merit": {
    "total": 400,
    "distinct_senders": 120,
    "transactions": 200,
    "observed_at": "2026-08-29T00:00:00.000Z"
  },
  "url": "https://bitcointalk.org/index.php?topic=3309245.0",
  "first_post": {
    "object": "post",
    "post_id": 34538660,
    "topic_id": 3309245,
    "post_number": 1,
    "is_op": true,
    "title": "Forget about exchanger search! Use BestChange!",
    "author": {
      "profile_id": 1978649,
      "username": "Best.Change",
      "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
    },
    "board": {
      "board_id": 84,
      "name": "Service Announcements"
    },
    "language": "en",
    "posted_at": "2018-04-12T00:00:00.000Z",
    "url": "https://bitcointalk.org/index.php?topic=3309245.msg34538660#msg34538660",
    "topic_url": "https://bitcointalk.org/index.php?topic=3309245.0",
    "content_html": "<p>BestChange.com helps compare exchangers.</p>",
    "indexed_at": "2026-08-29T12:00:00.000Z",
    "merit": {
      "total": 0,
      "distinct_senders": 0,
      "transactions": 0,
      "observed_at": null
    }
  },
  "latest_post": {
    "post_id": 67000000,
    "topic_id": 3309245,
    "post_number": 2400,
    "is_op": false,
    "title": "Forget about exchanger search! Use BestChange!",
    "author": {
      "profile_id": 1978649,
      "username": "Best.Change",
      "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
    },
    "board": {
      "board_id": 84,
      "name": "Service Announcements"
    },
    "language": "en",
    "posted_at": "2026-08-29T00:00:00.000Z",
    "url": "https://bitcointalk.org/index.php?topic=3309245.msg67000000#msg67000000",
    "topic_url": "https://bitcointalk.org/index.php?topic=3309245.0"
  }
}
Profile by ID response
{
  "object": "profile",
  "profile_id": 1978649,
  "username": "Best.Change",
  "url": "https://bitcointalk.org/index.php?action=profile;u=1978649",
  "corpus": {
    "post_count": 1200,
    "topic_count": 18,
    "first_post_at": "2017-11-01T00:00:00.000Z",
    "last_post_at": "2026-08-29T00:00:00.000Z",
    "derived_from": "distinct indexed posts"
  },
  "recent_posts": [
    {
      "post_id": 67000000,
      "topic_id": 3309245,
      "post_number": 2400,
      "is_op": false,
      "title": "Forget about exchanger search! Use BestChange!",
      "author": {
        "profile_id": 1978649,
        "username": "Best.Change",
        "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
      },
      "board": {
        "board_id": 84,
        "name": "Service Announcements"
      },
      "language": "en",
      "posted_at": "2026-08-29T00:00:00.000Z",
      "url": "https://bitcointalk.org/index.php?topic=3309245.msg67000000#msg67000000",
      "topic_url": "https://bitcointalk.org/index.php?topic=3309245.0"
    }
  ]
}
Posts in a topic response (illustrative cursor)
{
  "object": "post_list",
  "scope": {
    "type": "topic",
    "id": 5480200
  },
  "order": "asc",
  "limit": 50,
  "filters": {
    "date_from": "2026-09-09T00:00:00.000Z",
    "date_to": null,
    "board_id": null,
    "author_uid": null,
    "topic_id": null
  },
  "snapshot_at": "2026-09-26T12:00:00.000Z",
  "cursor_expires_at": "2026-09-26T12:05:00.000Z",
  "has_more": true,
  "next_cursor": "opaque_payload.opaque_signature",
  "data": [
    {
      "object": "post",
      "post_id": 67000001,
      "topic_id": 5480200,
      "post_number": 2,
      "is_op": false,
      "title": "Example topic",
      "author": {
        "profile_id": 1978649,
        "username": "Best.Change",
        "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
      },
      "board": {
        "board_id": 84,
        "name": "Service Announcements"
      },
      "language": "en",
      "posted_at": "2026-09-09T12:30:00.000Z",
      "url": "https://bitcointalk.org/index.php?topic=5480200.msg67000001#msg67000001",
      "topic_url": "https://bitcointalk.org/index.php?topic=5480200.0",
      "content_html": "<p>Illustrative indexed post content.</p>",
      "indexed_at": "2026-09-26T11:59:00.000Z",
      "merit": {
        "total": 0,
        "distinct_senders": 0,
        "transactions": 0,
        "observed_at": null
      }
    }
  ]
}
Posts by a profile response (illustrative cursor)
{
  "object": "post_list",
  "scope": {
    "type": "profile",
    "id": 1978649
  },
  "order": "asc",
  "limit": 50,
  "filters": {
    "date_from": "2026-09-09T00:00:00.000Z",
    "date_to": null,
    "board_id": null,
    "author_uid": null,
    "topic_id": null
  },
  "snapshot_at": "2026-09-26T12:00:00.000Z",
  "cursor_expires_at": "2026-09-26T12:05:00.000Z",
  "has_more": true,
  "next_cursor": "opaque_payload.opaque_signature",
  "data": [
    {
      "object": "post",
      "post_id": 67000001,
      "topic_id": 5480200,
      "post_number": 2,
      "is_op": false,
      "title": "Example topic",
      "author": {
        "profile_id": 1978649,
        "username": "Best.Change",
        "url": "https://bitcointalk.org/index.php?action=profile;u=1978649"
      },
      "board": {
        "board_id": 84,
        "name": "Service Announcements"
      },
      "language": "en",
      "posted_at": "2026-09-09T12:30:00.000Z",
      "url": "https://bitcointalk.org/index.php?topic=5480200.msg67000001#msg67000001",
      "topic_url": "https://bitcointalk.org/index.php?topic=5480200.0",
      "content_html": "<p>Illustrative indexed post content.</p>",
      "indexed_at": "2026-09-26T11:59:00.000Z",
      "merit": {
        "total": 0,
        "distinct_senders": 0,
        "transactions": 0,
        "observed_at": null
      }
    }
  ]
}

Try it

Send a real request without leaving the documentation. Your key stays in this page’s memory and is sent only to the same-origin TalkSearch API.

Used only for this browser request. TalkSearch does not save it in this page.

Options

A successful request consumes one prepaid credit. Invalid, not-found, expired-cursor, and failed requests are not charged.

ResponseWaiting for a request

Choose an operation, enter a revocable API key, and inspect the live JSON response and metering headers.

Errors

HTTPMeaningWhat to do
400A query, resource ID, collection option, or cursor is invalid. Collection options cannot be unknown, repeated, empty, or different from the cursor’s original options.Correct the request parameters. For a different collection scope or filter, start without a cursor.
401The API key is missing, invalid, expired, or revoked.Use an active key or renew an expired key from the developer dashboard.
402The account has insufficient prepaid credits.Top up the account before retrying.
403The source IP is not allowed for this API key.Add the returned sourceIp to the key allowlist, or send the request from an allowed address.
404An individual resource lookup did not find the requested post, topic, or profile. A collection with no indexed posts instead returns 200 and an empty list.Check the Bitcointalk ID. Not-found lookups are not charged.
410A collection cursor or its indexed snapshot has expired.Start a new collection request without a cursor. Expired requests are not charged.
429The API-key rate limit was exceeded.Wait until X-RateLimit-Reset, then retry with backoff.
503The requested operation could not complete.Retry later. The failed request is not charged.

Metering and limits

One credit per success

A completed search, returned resource, or successful collection page charges one credit. This includes empty terminal collection pages. Invalid requests, not-found resources, expired cursors, and service failures are not charged.

120 requests per minute

The limit applies per API key. Use the X-RateLimit-* response headers to schedule retries.

Successful responses also return X-Request-Id, X-Credits-Charged, and X-Credits-Remaining.