Create and Export your API Key

Create an API Key

Start by creating an API Key on the dashboard, which you can use to store your API key and track your usage.

You can then store the API Key and export it as an environment variable in your development environment.

export ZEROENTROPY_API_KEY="your_api_key"

Getting Started

After checking out the Core Concepts, you’ll be ready to use the API. We offer many different ways to access our API:

  1. Using our official SDKs for Python and TypeScript / JavaScript as shown below.
pip install zeroentropy
  1. Using our interactive API Reference. Simply drop your API Key into the “Authorization” button and use our interactive API to try it out.
    • You can copy example queries using cURL, Python, Javascript into your development environment.
  2. Using https://go.zeroentropy.dev/openapi.json to access the API through an API platform such as Thunder Client or Postman.
    • For example, in Postman, go to File -> Import, and then paste https://go.zeroentropy.dev/openapi.json into the prompt. You’ll have to set the bearerToken variable to your API Key.
  3. Using our SwaggerUI interface, simply drop your API Key into “Authorize” button in the top-right corner.

Send your First Query

from zeroentropy import ZeroEntropy
import time
zclient = ZeroEntropy()

# Create a collection
collection = zclient.collections.add(collection_name="default")

# Add a text file to the collection
document = zclient.documents.add(
    collection_name="default",
    path="docs/document.txt",
    content={
        "type": "text",
        "text": "My favorite apple is the Granny Smith.",
    },
)

# Wait until the document is indexed
while True:
    status = zclient.documents.get_info(collection_name="default", path="docs/document.txt")
    if status.document.index_status == "indexed":
        print("Document is indexed.")
        break
    time.sleep(1)

# Query the collection
response = zclient.queries.top_documents(
    collection_name="default",
    query="What is the best apple?",
    k=1,
)
print(response.results)

Prompt your LLM to use ZeroEntropy

Prompt an LLM to use ZeroEntropy

Click this card to copy a prompt for using ZeroEntropy with your LLM. You can save it as a text file and reference it in tools like Cursor.

copy
ZeroEntropy SDK Helper

ZeroEntropy can be installed using:
	•	Python: pip install zeroentropy
	•	Node.js: npm install zeroentropy

Client Usage

from zeroentropy import ZeroEntropy
client = ZeroEntropy(api_key="your_api_key")

The following SDK methods are available:

📌 API Methods & Expected Outputs

Each method returns structured responses defined by pydantic.BaseModel.

📂 Collections
	•	client.collections.add(collection_name: str) -> None
        Always specify a collection name using client.collections.add(collection_name="my_collection")
        If the collection already exists, it will be throw an error, so you need to check if the collection exists first.
	•	client.collections.get_list() -> List[str]
	•	client.collections.delete(collection_name: str) -> None

📄 Documents
	•	client.documents.add(collection_name: str, path: str, content, metadata: dict = None, overwrite: bool = False) -> None
        The add method already handles parsing for PDFs etc. The content dict can take the following formats:
        content={"type":"auto", "base64_data":"my_document.pdf"} for a PDF, content={"type":"text", "text":"my_document.pdf"} for a text file, and content={"type":"text-pages", "pages":[ "page 1 content", "page 2 content"]} for pages of text.
        If the document already exists, it will be throw an error, so you need to check if the document exists first.
	•	client.documents.get_info(collection_name: str, path: str, include_content: bool = False) -> DocumentResponse
	•	client.documents.get_info_list(collection_name: str, limit: int = 1024, id_gt: Optional[str] = None) -> List[DocumentMetadataResponse]
	•	client.documents.update(collection_name: str, path: str, metadata: Optional[dict]) -> UpdateDocumentResponse
	•	client.documents.delete(collection_name: str, path: str) -> None

🔎 Queries
	•	client.queries.top_documents(collection_name: str, query: str, k: int, filter: Optional[dict] = None, include_metadata: bool = False, latency_mode: str = "low") -> List[DocumentRetrievalResponse]
	•	client.queries.top_pages(collection_name: str, query: str, k: int, filter: Optional[dict] = None, include_content: bool = False, latency_mode: str = "low") -> List[PageRetrievalResponse]
	•	client.queries.top_snippets(collection_name: str, query: str, k: int, filter: Optional[dict] = None, precise_responses: bool = False) -> List[SnippetResponse]

📊 Status
	•	client.status.get(collection_name: Optional[str] = None) -> StatusResponse

📑 Parsers
	•	client.parsers.parse_document(base64_data: str) -> ParseDocumentResponse

📌 Expected Response Models

All responses return structured BaseModel objects as follows:

1️⃣ DocumentResponse

Used in get_info()

python
class DocumentResponse(BaseModel):
    id: str  # UUID of the document
    collection_name: str
    path: str
    metadata: Dict[str, str]  # Metadata key-value pairs
    index_status: str  # Enum: "parsing_failed", "not_parsed", "parsing", "not_indexed", "indexing", "indexed"
    num_pages: Optional[int] = None  # Can be null
    content: Optional[str] = None  # Null unless `include_content=True`

2️⃣ UpdateDocumentResponse

Used in update()

python
class UpdateDocumentResponse(BaseModel):
    previous_id: str  # Old document UUID
    new_id: str  # New updated document UUID

3️⃣ DocumentRetrievalResponse

Used in top_documents()
python
class DocumentRetrievalResponse(BaseModel):
    results: List[Response] 
class Response(BaseModel):
    path: str
    metadata: Optional[Dict[str, str]] = None  # Null if `include_metadata=False`
    score: float  # Relevancy score

4️⃣ PageRetrievalResponse

Used in top_pages()

python
class PageRetrievalResponse(BaseModel):
    results: List[Response] 
class Response(BaseModel):
    path: str  # Document path
    page_index: int  # 0-indexed page number
    score: float  # Relevancy score
    content: Optional[str] = None  # Null if `include_content=False`

5️⃣ SnippetResponse

Used in top_snippets()

python
class SnippetResponse(BaseModel):
    results: List[Response] 
class Response(BaseModel):
    path: str
    start_index: int  # Start character index of snippet
    end_index: int  # End character index of snippet
    page_span: List[int]  # (start_page, end_page) index range
    content: Optional[str] = None  # Snippet text
    score: float  # Relevancy score

6️⃣ StatusResponse

Used in status.get()

python
class StatusResponse(BaseModel):
    num_documents: int  # Total document count
    num_parsing_documents: int  # Documents still being parsed
    num_indexing_documents: int  # Documents currently being indexed
    num_indexed_documents: int  # Successfully indexed documents
    num_failed_documents: int  # Documents that failed

7️⃣ ParseDocumentResponse

Used in parse_document()

python
class ParseDocumentResponse(BaseModel):
    pages: List[str]  # List of extracted page contents

📌 Additional Notes
	1.	Cursor should always use these BaseModels when generating SDK-based responses.
	2.	Metadata Filtering
	•	Document metadata is always dict[str, str | list[str]].
	•	Filters support operators: $eq, $ne, $gt, $gte, $lt, $lte (for equality and range queries).
	3.	Responses will always match these structures unless otherwise stated.