Connect Censys to AI Agents: Automate Discovery and Asset Management
Learn how to connect Censys to AI Agents using Truto's /tools endpoint. Build autonomous discovery, threat hunting, and asset management workflows without custom code.
You want to connect Censys to an AI agent so your security operations center (SOC) can autonomously hunt threats, track host histories, and execute complex asset discovery workflows based on real-time internet intelligence. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to maintain custom API wrappers.
Giving a Large Language Model (LLM) read and write access to your Censys instance is an engineering headache. You either spend weeks building, hosting, and maintaining a custom connector that understands the nuances of CenQL, or you use a managed infrastructure layer that handles the boilerplate for you. If your team uses ChatGPT, check out our guide on connecting Censys to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Censys to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.
This guide breaks down exactly how to fetch AI-ready tools for Censys, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex threat-hunting workflows. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.
The Engineering Reality of Custom Censys Connectors
Building AI agents is easy. Connecting them to external SaaS and security APIs is hard. Giving an LLM access to external threat intelligence sounds simple in a prototype. You write a Node.js function that makes a fetch request and wrap it in an @tool decorator. In production, this approach collapses entirely, especially with an ecosystem as complex as Censys.
If you decide to build the integration yourself, you own the entire API lifecycle. Censys's Search and Attack Surface Management (ASM) APIs introduce several highly specific integration challenges that break standard LLM assumptions.
The CenQL Syntax Trap
Censys relies heavily on CenQL (the Censys Search Language) for querying its global data sets. When an agent needs to retrieve a list of hosts running an outdated version of Apache in a specific autonomous system, standard REST conventions fail. The agent must formulate a valid CenQL query like services.software.vendor: "Apache" and services.port: 443 and location.country: "Germany".
If you hand-code this integration, you have to write complex system prompts to teach the LLM the exact syntax of CenQL, including the difference between legacy CSL queries and modern Platform queries. When the LLM inevitably hallucinates a query operator or nests a field incorrectly, the API throws a 400 Bad Request, and the agent loop crashes. Truto's tool layer provides structured query parameters and automatically handles formatting, while providing endpoints specifically designed to validate or aggregate these queries before executing massive data pulls.
Asynchronous Job Polling
Threat hunting is rarely a synchronous operation. Many high-value endpoints in Censys - like Live Discovery scans or CensEye pivot analyses - are deeply asynchronous. You cannot just send a POST request and get a populated JSON array of vulnerabilities back in 200 milliseconds.
An LLM natively assumes that when it calls a function, the function returns the final answer. With Censys, calling create_a_censys_censeye_job returns a job_id with a status: pending. If you build this manually, you must teach the agent to wait, handle timeouts, and repeatedly call get_single_censys_censeye_job_by_id until the status is complete, and only then call censys_censeye_jobs_list_results. This complex state machine is notoriously difficult for LLMs to manage without hallucinating intermediate steps.
Deprecated Endpoints and Payload Complexity
The Censys API has evolved, leading to multiple ways to fetch data, some of which are strictly deprecated. For example, retrieving multiple hosts or certificates via GET requests with massive URL query strings is deprecated. The modern approach requires using POST variants like the bulk_get endpoints.
Furthermore, the return payloads are heavily nested. A single host object contains ip, location, autonomous_system, whois, services (which itself contains port, protocol, banner_hash_sha256), and deep extensions. Dumping raw Censys payloads into an LLM context window will instantly blow past token limits. You need an abstraction layer that trims the fat, handles the bulk POST logic internally, and returns unified, deterministic schemas to the agent.
Credit Consumption and Rate Limits
Censys meters API usage tightly. Queries, aggregations, and enrichments consume credits. An autonomous AI agent trapped in a hallucination loop could rapidly drain an organization's monthly credit quota. Moreover, Censys enforces strict HTTP 429 rate limits. You cannot just blast the API with concurrent requests while an LLM parallelizes its tool calls.
Censys Hero Tools for AI Agents
A unified tool layer collapses these complexities behind standard JSON schemas. Your agent sees deterministic functions like censys_hosts_enrichment and censys_certificates_bulk_get. It does not have to worry about whether to use GET or POST, or how to parse the HTTP response headers.
Here are the critical tools you should expose to your security agents to execute high-leverage Censys workflows.
1. list_all_censys_search
This tool allows the agent to search Censys global assets using a CenQL query string. It returns host configurations and matched services. Use this as the primary entry point for broad threat discovery.
Contextual usage notes: The tool enforces a maximum of 100 results per page. Ensure the agent uses specific CenQL strings rather than broad keywords to prevent overwhelming the context window.
"Find all hosts in the US running Microsoft IIS version 8.5 and list their IP addresses using the Censys search tool."
2. censys_hosts_enrichment
Once an agent identifies a suspicious IP, it needs deep context. This tool retrieves enrichment data for a single host, including reputation, GreyNoise integration data, network details, and privacy labels.
Contextual usage notes: This tool requires a valid host_ip. It is best used in a loop after a bulk search, allowing the agent to filter out false positives based on reputation scoring.
"Take this list of 5 suspicious IP addresses and get their full enrichment profiles. Flag any that have a negative reputation score or known GreyNoise tags."
3. censys_certificates_bulk_get
Agents frequently need to cross-reference infrastructure using TLS certificates. This POST-based bulk tool retrieves multiple Censys certificates by their SHA-256 fingerprints in a single request, returning parsed details, validation levels, and revocation status.
Contextual usage notes: Prefer this over the deprecated GET method. Pass an array of certificate_ids (SHA-256 fingerprints) to minimize network round trips and token usage.
"We found three suspicious TLS certificates. Use their SHA-256 fingerprints to retrieve their validation status and check if they have been revoked."
4. create_a_censys_censeye_job
This tool initiates an asynchronous CensEye pivot analysis job for a host, web property, or certificate. It allows the agent to discover related infrastructure programmatically.
Contextual usage notes: The agent must provide exactly one target type (host_id, webproperty_id, or certificate_id). Instruct the agent to capture the returned job_id and transition to a polling state.
"Run a CensEye pivot analysis on certificate fingerprint 9b3a... to find all related web properties. Let me know when the job has started."
5. censys_dns_ip_resolution_ranges
DNS is critical for mapping attack surfaces. This tool retrieves DNS names that resolved to a specific IP in Censys, broken down by historical time ranges.
Contextual usage notes: Excellent for incident response to determine what domain was hosted on a malicious IP at the specific time an alert fired.
"Check the DNS resolution history for IP 192.0.2.50. I need to know which domains were pointing to this address between March 1st and March 15th."
6. create_a_censys_discovery_scan
This tool initiates a Live Discovery scan on a target object to find unindexed or newly surfaced assets in real time.
Contextual usage notes: Discovery scans take time and consume credits. Ensure the agent is prompted to only run live scans when historical data is insufficient or explicitly requested by the analyst.
"The historical data for this subnet is stale. Initiate a Live Discovery scan on the target block and report back the scan ID."
To view the complete inventory of available Censys tools, including credit usage reporting, collection management, and legacy query conversion utilities, visit the Censys integration page.
Workflows in Action
Individual tools are useful, but the real power of an AI agent comes from chaining these tools together to execute multi-step playbooks. Here are concrete examples of how specific personas use these tools.
Scenario 1: Automated Threat Hunting (SecOps Analyst)
When a new critical vulnerability is announced, security analysts waste hours querying Shodan or Censys manually, exporting CSVs, and enriching IPs. An AI agent automates this end-to-end.
"Search Censys for any active hosts running 'Confluence 8.5.3'. For every IP you find, pull the host enrichment data and check if it has a malicious reputation. Finally, look up the DNS resolution history for any malicious IPs to identify the associated domains."
Execution Steps:
list_all_censys_search: The agent executes a CenQL query (services.software.product: "Confluence" and services.software.version: "8.5.3") and retrieves a list of IPs.censys_hosts_enrichment: The agent loops through the returned IPs, calling this tool to gather reputation and GreyNoise data.censys_dns_ip_resolution_ranges: For any IP flagged as suspicious during enrichment, the agent queries the DNS history to map the infrastructure to human-readable domain names.
Result: The analyst receives a highly curated report of vulnerable, actively malicious infrastructure complete with associated domains, turning a three-hour manual hunt into a three-minute automated job.
Scenario 2: Shadow IT Discovery (IT Administrator)
Organizations frequently spin up rogue web servers outside of managed infrastructure. IT admins need to track these down before they become entry points.
"Initiate a Live Discovery scan on our newly acquired subsidiary's /24 subnet. Once complete, list all the certificates found and fetch their bulk parsed details to check if they are using self-signed or expired certs."
Execution Steps:
create_a_censys_discovery_scan: The agent triggers the live scan against the provided target subnet and captures the resulting scan ID.- (Polling state): The agent waits and polls the scan status (using a tracking tool) until the job completes.
censys_certificates_bulk_get: The agent extracts the SHA-256 fingerprints from the newly discovered assets and passes them in a single batch to check validation and revocation statuses.
Result: The IT admin gets an immediate alert regarding unmanaged servers running expired or untrusted TLS certificates, allowing them to remediate shadow IT before an audit flags it.
Building Multi-Step Workflows
To connect Censys to your LLM, you will use Truto's /tools API. Truto exposes every Resource and Method defined on an integration as a proxy API, complete with JSON schemas describing the inputs and outputs. You retrieve these dynamically and bind them to your agent framework.
Whether you are using LangChain, LangGraph, CrewAI, or the Vercel AI SDK, the architecture is framework-agnostic. The LLM communicates with your agent framework, which in turn passes structured tool calls to the Truto unified layer. Truto handles the authentication, pagination, and query parameter processing, and executes the raw request against Censys.
Handling API Rate Limits
It is critical to understand that Truto does not automatically retry, throttle, or apply backoff on rate limit errors. When the upstream Censys API returns an HTTP 429 (Too Many Requests), Truto passes that error directly back to your agent framework.
However, Truto normalizes the upstream rate limit information into standardized IETF headers across all integrations:
ratelimit-limit: The total allowed requests in the current window.ratelimit-remaining: The number of requests remaining in the current window.ratelimit-reset: The time at which the rate limit window resets.
Your application layer is responsible for reading these headers, pausing execution, and retrying the request.
Here is how that flow looks architecturally:
flowchart TD
Agent["AI Agent (LangChain)"]
Truto["Truto Unified Tool Layer"]
Censys["Censys API"]
Agent -->|"Tool Call: censys_hosts_enrichment"| Truto
Truto -->|"Authenticated API Request"| Censys
Censys -->|"HTTP 429 Too Many Requests"| Truto
Truto -->|"HTTP 429 + Normalized Headers"| Agent
Agent -->|"Read ratelimit-reset<br>Sleep thread<br>Retry Request"| Truto
Truto -->|"Authenticated API Request"| Censys
Censys -->|"HTTP 200 OK"| Truto
Truto -->|"Structured JSON Schema"| AgentImplementation with LangChain.js
Below is a production-ready example using the @trutohq/truto-langchainjs-toolset and LangChain.js. We implement a custom fetch interceptor to handle the 429 rate limit backoff automatically before the error ever reaches the LLM.
First, install the necessary dependencies:
npm install @trutohq/truto-langchainjs-toolset @langchain/openai langchainNow, build the agent loop:
import { TrutoToolManager } from "@trutohq/truto-langchainjs-toolset";
import { ChatOpenAI } from "@langchain/openai";
import { createOpenAIFunctionsAgent, AgentExecutor } from "langchain/agents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
// 1. Implement an auto-retry fetch wrapper for Truto's standardized 429 headers
const fetchWithRateLimitBackoff = async (url: string, options: RequestInit) => {
let retries = 3;
while (retries > 0) {
const response = await fetch(url, options);
if (response.status === 429) {
// Truto normalizes the upstream rate limit reset time
const resetHeader = response.headers.get('ratelimit-reset');
const resetTime = resetHeader ? parseInt(resetHeader, 10) * 1000 : Date.now() + 5000;
const waitTime = Math.max(resetTime - Date.now(), 1000);
console.log(`[Rate Limit Hit] Sleeping for ${waitTime}ms before retrying...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
retries--;
continue;
}
return response;
}
throw new Error("Max retries exceeded after HTTP 429");
};
async function runCensysAgent() {
// 2. Initialize the Truto Tool Manager with your Integrated Account ID
const toolManager = new TrutoToolManager({
trutoToken: process.env.TRUTO_API_KEY,
integratedAccountId: "your_censys_integrated_account_id",
fetchFn: fetchWithRateLimitBackoff // Inject the backoff logic
});
// 3. Fetch tools dynamically from [Truto's /tools endpoint](/best-unified-api-for-llm-function-calling-ai-agent-tools-2026/)
// We filter to only retrieve Read and Custom methods to prevent accidental data deletion
const tools = await toolManager.getTools({
methods: ["read", "custom"]
});
console.log(`Loaded ${tools.length} Censys tools for the agent.`);
// 4. Initialize the LLM and bind the tools
const llm = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});
const prompt = ChatPromptTemplate.fromMessages([
["system", `You are an elite SecOps AI agent. You have access to Censys for threat intelligence.
When using Censys tools, prioritize bulk endpoints like censys_certificates_bulk_get over iterative GETs.
If a job requires polling (like CensEye), inform the user that you are initiating the job.
Always provide a concise summary of the intelligence gathered.`],
["human", "{input}"],
["placeholder", "{agent_scratchpad}"],
]);
// 5. Create the Agent Executor
const agent = await createOpenAIFunctionsAgent({
llm,
tools,
prompt,
});
const agentExecutor = new AgentExecutor({
agent,
tools,
verbose: true,
});
// 6. Execute a multi-step threat hunt workflow
const result = await agentExecutor.invoke({
input: "Search Censys for hosts running 'Apache Tomcat' in Japan. Grab the first 3 IPs, pull their enrichment profiles, and tell me if any of them have negative reputation scores."
});
console.log("\n=== Agent Output ===");
console.log(result.output);
}
runCensysAgent().catch(console.error);Why This Architecture Scales
By fetching tools dynamically via /tools, your agent is completely isolated from underlying API schema changes. If Censys deprecates a field or introduces a new CenQL parameter, Truto updates the integration layer. The next time your application calls toolManager.getTools(), the LLM receives the updated JSON schema, and execution continues without you ever having to open a pull request or deploy new integration code.
Moving Beyond Point-to-Point Connectors
Giving AI agents access to security data is no longer an AI challenge; it is a systems integration challenge. Hardcoding API requests, managing rate limit headers, and parsing massively nested JSON payloads in your agent framework ensures your product will remain a brittle prototype.
By leveraging a unified tool layer, you ensure that your agents interact with a stable, deterministic, and safe interface. You handle the auth and rate limiting at the infrastructure level, allowing your LLM to focus purely on reasoning and threat analysis.
FAQ
- Does Truto handle Censys API rate limits automatically?
- No. Truto passes upstream HTTP 429 errors directly to the caller. However, Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) so your application layer can implement consistent backoff and retry logic.
- Can I use these Censys tools with any AI agent framework?
- Yes. Truto's /tools endpoint returns standard JSON schemas that can be bound to any framework, including LangChain, LangGraph, CrewAI, or the Vercel AI SDK. It is completely framework-agnostic.
- How do AI agents handle asynchronous Censys scans?
- Agents must be prompted to use the asynchronous job tools (like create_a_censys_discovery_scan) to get a job_id, and then use the corresponding retrieval tools to poll the status until the scan completes before fetching the results.
- Why shouldn't I just write a custom integration for Censys?
- Censys has complex query languages (CenQL), deeply nested return payloads, strict pagination, and deprecated endpoints. Managing this logic manually pushes these quirks into your LLM's context window, leading to hallucinations and brittle workflows. A unified tool layer collapses these complexities behind stable schemas.