Overview
AgentKey’s execution engine powers your AI agents to take real actions across connected platforms. Once a user has connected their accounts, you can trigger sophisticated automations, data extractions, and workflows that run in authenticated browser sessions.
How It Works
When users authenticate with platforms through our SDKs, AgentKey securely captures browser state, authentication signals, and optimizes proxy selection. Our AI agents then execute computer-use automations in managed browser environments that perfectly replicate authentic user sessions.
The magic: You simply describe what you want accomplished, and AgentKey handles all the complex browser orchestration, anti-detection measures, and session management behind the scenes.
AgentKey’s infrastructure includes:
- Managed Browser Infrastructure: Scalable, secure browser pools with built-in session retention and auto-healing
- Geo-Targeted Proxies: Compliance-ready residential proxies, local to your users’ regions for reliable access
- Advanced Stealth & Evasion: Dynamic fingerprint spoofing and anti-detection tech to bypass bot defenses seamlessly
- AI-Powered Browser Agents: Leverage OpenAI/Anthropic CUA for intelligent, multi-step automation of complex workflows
- Session Continuity: Persistent authentication states and storage across every interaction, automatically managed
- BlockGuard™ Protection: Automated monitoring and evasion to keep user accounts unblocked and fraud-model resistant
Execution Structure
Every agent execution requires these key components:
const executionRequest = {
accessToken: "ak-access-dev-...", // User's access token
action: "Description of what the agent should do",
startingUrl: "https://platform.com/starting-page", // Required starting URL
parameters: {
// Optional additional parameters
},
responseFormat: {
// Optional expected structure of the response
}
};
Core Parameters
Parameter | Type | Required | Description |
---|
accessToken | string | ✅ | User’s AgentKey access token |
action | string | ✅ | Description of the task to perform |
startingUrl | string | ✅ | Valid URL to begin execution |
parameters | object | ❌ | Additional optional parameters |
responseFormat | object | ❌ | Optional expected response structure |
Parameters Object (Optional)
The parameters
field accepts any key-value pairs for additional context or configuration:
// Example parameters
{
parameters: {
maxResults: 20,
department: "engineering",
location: "san francisco",
// Any custom parameters specific to your use case
}
}
These are examples and not restricted - users can specify their own response formats. Ideally, each response should be able to be fetched on the same page vs complex navigations.
const responseFormat = {
profile: {
name: "string - Full name",
headline: "string - Professional headline",
location: "string - Current location",
connections: "number - Connection count if visible",
about: "string - About section if visible"
},
jobs: [
{
company: "string - Company name",
jobTitle: "string - Position title",
dates: "string - Employment period",
duration: "string - Duration if visible",
location: "string - Job location if available"
}
],
education: [
{
school: "string - Institution name",
degree: "string - Degree or field",
dates: "string - Attendance period"
}
],
skills: ["string - Skill names"],
totalJobs: "number - Count of jobs found",
extractedAt: "string - ISO timestamp"
};
Execution Examples
⚡ Optimize with startingUrl
Key tip: Always use the most specific starting URL to minimize agent navigation and improve efficiency.
✅ Good: Direct profile URL
❌ Avoid: Generic starting pages
// ✅ GOOD: Direct LinkedIn profile URL
startingUrl: "https://www.linkedin.com/in/sagar-jaiswall/"
// ❌ AVOID: Generic LinkedIn homepage (requires navigation)
startingUrl: "https://www.linkedin.com/"
Request:
const extractLinkedInProfile = async (accessToken: string) => {
const response = await fetch('/api/agent-requests', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-id': 'your-client-id',
'x-client-secret': 'your-client-secret',
},
body: JSON.stringify({
accessToken: accessToken,
action: 'Get me the bio of sagar profile',
startingUrl: 'https://www.linkedin.com/in/sagar-jaiswall/', // Direct profile URL
parameters: {},
responseFormat: {
jobs: [
{
company: 'string - Company name',
jobTitle: 'string - Job title/position',
dates: 'string - Employment dates (e.g., \'Jan 2020 - Present\', \'Mar 2018 - Dec 2019\')',
duration: 'string - Optional: Duration (e.g., \'2 years 3 months\')',
location: 'string - Optional: Job location if visible'
}
],
totalJobs: 'number - Total number of jobs found'
}
}),
});
const data = await response.json();
console.log('Profile extraction started:', data.requestId);
};
Response:
{
"success": true,
"data": {
"requestId": "e3a1ac73-a80d-47c8-8a72-779c8707b4eb",
"status": "COMPLETED",
"providerId": "d3982096-ce7d-4f46-ae53-714b3e6304d2",
"action": "Get me the bio of sagar profile",
"result": {
"jobs": [
{
"dates": "Jun 2017 - Sep 2017",
"company": "Lutra Consulting",
"duration": "4 mos",
"jobTitle": "Application Developer - GIS Software",
"location": "West Sussex, England, United Kingdom · Remote"
},
{
"dates": "Jun 2016 - Sep 2016",
"company": "Visa",
"duration": "4 mos",
"jobTitle": "Data Engineer - Cross-Border Banking Solutions",
"location": "Reading, England, United Kingdom · On-site"
},
{
"dates": "Jun 2014 - Oct 2014",
"company": "Technotomy Ltd",
"duration": "5 mos",
"jobTitle": "Computer Vision Research Consultant",
"location": "Guildford, England, United Kingdom · On-site"
}
],
"totalJobs": 3
},
"executionTimeMs": 53651,
"createdAt": "2025-06-05T18:58:31.974Z",
"completedAt": "2025-06-05T18:59:31.279Z"
}
}
Example 2: Comprehensive Profile Analysis
// Extract detailed LinkedIn profile with work history analysis
const detailedExtraction = {
accessToken: "ak-access-dev-abc123def456",
action: "Extract complete LinkedIn profile information including detailed work history and calculate total years of experience",
startingUrl: "https://linkedin.com/in/john-doe-tech",
parameters: {},
responseFormat: {
profile: {
name: "string - Full name",
headline: "string - Professional headline",
location: "string - Current location",
about: "string - About section content",
connections: "number - Connection count if visible",
profileUrl: "string - LinkedIn profile URL"
},
jobs: [
{
company: "string - Company name",
jobTitle: "string - Position title",
dates: "string - Employment period",
duration: "string - Duration if visible",
location: "string - Job location",
description: "string - Job description if visible",
skills: ["string - Skills mentioned for this role"]
}
],
education: [
{
school: "string - Institution name",
degree: "string - Degree type and field",
dates: "string - Attendance period",
location: "string - School location if visible"
}
],
skills: ["string - All listed skills"],
certifications: [
{
name: "string - Certification name",
issuer: "string - Issuing organization",
date: "string - Issue date if visible"
}
],
totalExperience: "string - Calculated years of experience",
currentRole: "string - Current job title and company",
industry: "string - Professional industry",
extractedAt: "string - ISO timestamp"
}
};
Example 3: Company Employee Search
// Search for employees at a specific company
const employeeSearch = {
accessToken: "ak-access-dev-xyz789abc",
action: "Find employees working at TechCorp in engineering roles",
startingUrl: "https://linkedin.com/company/techcorp",
parameters: {
searchFilters: {
department: "engineering",
location: "san francisco"
},
maxResults: 20
},
responseFormat: {
company: {
name: "string - Company name",
industry: "string - Company industry",
size: "string - Employee count range",
location: "string - Company headquarters"
},
employees: [
{
name: "string - Employee name",
title: "string - Current job title",
location: "string - Employee location",
profileUrl: "string - LinkedIn profile URL",
tenure: "string - Time at company if visible",
previousRole: "string - Previous role if visible"
}
],
searchCriteria: {
department: "string - Department searched",
location: "string - Location filter applied"
},
totalFound: "number - Total employees found",
extractedAt: "string - ISO timestamp"
}
};
Monitoring Executions
Checking Status
const checkStatus = async (requestId: string) => {
const response = await fetch(`/api/agent-requests/${requestId}`, {
headers: {
'x-client-id': 'your-client-id',
'x-client-secret': 'your-client-secret',
},
});
const execution = await response.json();
console.log(`Status: ${execution.status}`);
console.log(`Progress: ${execution.stepsCurrent}/${execution.stepsTotal}`);
if (execution.status === 'COMPLETED') {
console.log('Result:', execution.result);
} else if (execution.status === 'FAILED') {
console.error('Error:', execution.errorMessage);
}
};
Execution Statuses
Status | Description |
---|
PENDING | Execution queued, waiting to start |
PROCESSING | Agent is actively executing the task |
COMPLETED | Task completed successfully |
FAILED | Task failed with an error |
TIMEOUT | Task exceeded maximum duration |
Best Practices
1. Optimize for Minimal Actions
// ✅ Good: Specific, extraction-focused
{
action: "Extract visible job history from current LinkedIn profile page",
parameters: {}
}
// ❌ Avoid: Vague instructions that encourage exploration
{
action: "Get all information about this person"
}
2. Use Specific Starting URLs
// ✅ Good: Direct profile URL
{
startingUrl: "https://linkedin.com/in/specific-username",
action: "Extract profile information"
}
// ✅ Good: Specific company page
{
startingUrl: "https://linkedin.com/company/company-name",
action: "Get company information and recent posts"
}
// ❌ Less efficient: Generic starting point
{
startingUrl: "https://linkedin.com",
action: "Find and extract John Doe's profile"
}
// ✅ Good: Well-structured with clear types
{
responseFormat: {
contacts: [
{
name: "string - Full name",
title: "string - Job title",
company: "string - Company name",
profileUrl: "string - LinkedIn profile URL"
}
],
totalContacts: "number",
source: "string - Page/section extracted from"
}
}
4. Handle Errors Gracefully
const executeWithRetry = async (execution, maxRetries = 2) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch('/api/agent-requests', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-id': 'your-client-id',
'x-client-secret': 'your-client-secret',
},
body: JSON.stringify(execution),
});
if (response.ok) {
return await response.json();
}
if (attempt === maxRetries) {
throw new Error(`Failed after ${maxRetries} attempts`);
}
// Wait before retry
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
} catch (error) {
if (attempt === maxRetries) throw error;
}
}
};
Ready to start building automations? Check our Getting Started guide or explore the API reference.
Responses are generated using AI and may contain mistakes.