SDKs

Official Python, TypeScript and Go clients for the Redpine API.

Typed clients for the three languages most integrations are written in. All three are generated from the same OpenAPI spec as the API reference, so they expose the same endpoints, field names and errors as the REST API.

LanguagePackageSource
Python 3.10+redpine-sdk, import redpineredpine-ai/redpine-sdk-python
TypeScript, Node 20+@redpine-ai/sdkredpine-ai/redpine-sdk-js
Go 1.24+github.com/redpine-ai/redpine-sdk-goredpine-ai/redpine-sdk-go

Early release

The SDKs are at 0.x. The surface is stable for search, assisted search, collections and quota, but expect additive changes before 1.0. Report problems as issues on the language repository.

Install

pip install redpine-sdk

Configure

Every client reads REDPINE_API_KEY from the environment. Pass the key explicitly if you would rather not use the environment. A sandbox key (sk_test_) works everywhere a live key does and costs nothing. See Authentication.

from redpine import Redpine

client = Redpine()                              # reads REDPINE_API_KEY
client = Redpine(api_key="sk_test_...", timeout=30.0, max_retries=2)

Pass exactly one of collection (a single collection) or collections (several at once). The response shape is the one documented under Search: results, queryId, latencyMs. Python exposes the same fields in snake case.

r = client.search("your search query", collection="my-collection", limit=10)
for hit in r.results:
    print(hit.id, hit.text[:200])
print(r.query_id)

Don't know a collection name? collections() lists every collection the key can reach, at no cost.

for c in client.collections().collections:
    print(c.name)

Filters

F builds the structured filter documented in Filtering without hand-writing JSON. Operators are eq, ne, in, not_in, gt, gte, lt, lte and between. Combine with and, or and not. A raw filter object is accepted anywhere a built filter is.

from redpine import F

recent_high_impact = (
    F("publication_year").gte(2022)
    & F("journal_metric.2yr_mean_citedness").gte(5)
    & ~F("issn").in_(["1234-5679"])
)
r = client.search("crispr delivery", collections=["corpus"], filters=recent_high_impact)

Assisted search plans its own searches and verifies every result. Check status before reading results: it is results, clarification_needed or no_relevant_results.

a = client.assisted_search("what delivery vectors work for in vivo crispr?", collection="my-collection")
if a.status == "results":
    for hit in a.results:
        print(hit.relevance, hit.text[:200])
elif a.status == "clarification_needed":
    print(a.clarification.question)

Preview and unlock

Preview runs the search for free and returns teaser rows with a price per row; unlock pays for the rows you choose. Both return the same shape: results with locked, tokens and cost per row, plus costToUnlockRemaining and costCharged.

p = client.preview("your search query", collection="my-collection")
worth_it = [row.id for row in p.results if isinstance(row.tokens, int) and row.tokens < 300]
u = client.unlock(p.query_id, result_ids=worth_it)   # result_ids=None unlocks every row
for row in u.results:
    if not row.locked:
        print(row.text)
print("charged", u.cost_charged)

Re-sending an id you already paid for costs nothing, so retrying an unlock is safe.

Re-fetch results and check quota

Every search returns a queryId. Fetching it again within 7 days returns the same results without a new charge. Quota returns the daily and monthly counters described in Rate limits.

again = client.get_results(r.query_id)
q = client.quota()
print(q.daily_remaining, q.monthly_remaining)

Errors and retries

Non-2xx responses raise one typed error per status, carrying status, code, message and requestId from the error envelope. The clients retry 429 and 503 automatically, honouring Retry-After and otherwise backing off exponentially with jitter, up to maxRetries (default 2). Nothing else is retried.

HTTPPythonTypeScriptGo
401AuthErrorAuthError*AuthError
402InsufficientCreditsInsufficientCredits*InsufficientCreditsError
403AccessDeniedAccessDenied*AccessDeniedError
404NotFoundNotFound*NotFoundError
410ExpiredExpired*ExpiredError
422ValidationErrorValidationError*ValidationError
429QuotaExceeded (retry_after)QuotaExceeded (retryAfter)*QuotaExceededError (RetryAfter)
503AssistedUnavailableAssistedUnavailable*AssistedUnavailableError
otherRedpineErrorRedpineError*APIError
from redpine import QuotaExceeded, RedpineError

try:
    r = client.search("...", collection="my-collection")
except QuotaExceeded as e:
    print("retry after", e.retry_after)
except RedpineError as e:
    print(e.status, e.code, e.message, e.request_id)

Async Python

AsyncRedpine mirrors Redpine method for method on top of httpx. Use it as an async context manager or call aclose() when done.

from redpine import AsyncRedpine

async with AsyncRedpine() as client:
    r = await client.search("your search query", collection="my-collection")

Which one should I use?

Calling the API from a language not listed here, or from an environment where a dependency is unwelcome? The REST API in Getting started needs nothing beyond an HTTP client. Connecting an AI agent rather than writing code? Use MCP.

Was this page helpful?

On this page