langchain-pexafy (Python and JavaScript) gives LangChain and LangGraph agents three tools to find real, free-to-use photos (Unsplash, Pexels, Pixabay and more). Each photo comes back with its URL, alt text, licence and credit line.

Install

pip install -U langchain-pexafy
npm install langchain-pexafy @langchain/core
export PEXAFY_API_KEY="pexafy_..."
Create a free key at pexafy.com/dashboard/api-keys/create (no card).

Use

The examples also need LangChain’s agent and a chat model (any provider works):
pip install -U langchain langchain-anthropic
npm install langchain @langchain/anthropic
from langchain.agents import create_agent
from langchain_pexafy import PexafyToolkit

agent = create_agent("anthropic:claude-haiku-4-5", tools=PexafyToolkit().get_tools())

result = agent.invoke({"messages": [
    {"role": "user", "content": "Find a header photo for a post about remote work, with its credit line."}
]})
print(result["messages"][-1].content)
import { createAgent } from "langchain";
import { PexafyToolkit } from "langchain-pexafy";

const agent = createAgent({
  model: "anthropic:claude-haiku-4-5",
  tools: new PexafyToolkit().getTools(),
});

const result = await agent.invoke({
  messages: [{ role: "user", content: "Find a header photo for a post about remote work, with its credit line." }],
});
console.log(result.messages.at(-1)?.content);
Set ANTHROPIC_API_KEY for this example. create_agent / createAgent runs on LangGraph; the tools also work with ToolNode and any model’s bind_tools() / bindTools().

Tools

ClassTool nameArguments
PexafySearchPhotospexafy_search_photosquery, optional orientation, count
PexafyFindSimilarPhotospexafy_find_similar_photosphoto_id, optional count
PexafyGetPhotopexafy_get_photophoto_id
PexafyToolkit().get_tools() (Python) or new PexafyToolkit().getTools() (TypeScript) returns all three. Options on each: api_key / apiKey, max_results / maxResults (default 6, max 20).

Output

The tool message is a JSON list with one record per photo: photo_id, alt_text, url, thumbnail_url, width, height, orientation, dominant_color, photographer, source, source_page_url, license, credit. ToolMessage.artifact holds the full API records. On the free plan, show the credit line next to each photo you publish.

Errors

A spent quota, an unknown photo_id or a server error reaches the model as a tool error. A per-minute rate limit is retried automatically. An invalid key raises pexafy.AuthenticationError in Python; in TypeScript, LangGraph’s ToolNode passes it to the model as a tool error. See Errors & rate limits. Source on GitHub · PyPI · npm · MIT