Get Phantom running in under 5 minutes. No complex setup required.
npm install @vanishlabs/phantomPHANTOM_API_KEY=your_api_key_here
PHANTOM_PROJECT_ID=your_project_idimport { Phantom } from '@vanishlabs/phantom';
// Initialize once at app startup
Phantom.init({
apiKey: process.env.PHANTOM_API_KEY,
projectId: process.env.PHANTOM_PROJECT_ID,
});Missions are the core abstraction in Phantom. They represent a specific task your agent needs to accomplish, with built-in permission verification, intent checking, and audit logging.
import { Phantom } from '@vanishlabs/phantom';
async function bookFlightForUser(userId: string, destination: string) {
// Create a mission with intent and constraints
const mission = await Phantom.createMission({
userId,
intent: `Book flight to ${destination}`,
constraints: {
maxSpend: 500,
allowedActions: ['search_flights', 'book_ticket', 'send_confirmation']
}
});
try {
// Execute agent logic within the mission context
const result = await mission.run(async (context) => {
// Phantom automatically verifies:
// ✓ User identity and subscription status
// ✓ Budget constraints from Stripe
// ✓ Intent alignment for each action
const flights = await context.action('search_flights', {
destination,
maxPrice: 500
});
const booking = await context.action('book_ticket', {
flightId: flights[0].id
});
await context.action('send_confirmation', {
bookingId: booking.id,
email: context.user.email
});
return booking;
});
console.log('Mission completed:', result);
} catch (error) {
// If Phantom blocks an action, the mission fails safely
console.error('Mission failed:', error);
}
}from phantom import Phantom
async def book_flight_for_user(user_id: str, destination: str):
# Create a mission with intent and constraints
mission = await Phantom.create_mission(
user_id=user_id,
intent=f"Book flight to {destination}",
constraints={
"max_spend": 500,
"allowed_actions": ["search_flights", "book_ticket", "send_confirmation"]
}
)
try:
# Execute agent logic within the mission context
async with mission.run() as context:
flights = await context.action("search_flights", {
"destination": destination,
"max_price": 500
})
booking = await context.action("book_ticket", {
"flight_id": flights[0]["id"]
})
await context.action("send_confirmation", {
"booking_id": booking["id"],
"email": context.user.email
})
return booking
except PhantomSecurityError as e:
print(f"Mission blocked: {e}")
raiseAlready have agent code? Wrap it with the @Phantom.Protect decorator for instant authorization.
import { Phantom } from '@vanishlabs/phantom';
// Before: Manual permission checks everywhere
async function deleteUserData(userId: string, dataId: string) {
if (!user.isAdmin) throw new Error('Unauthorized');
if (!user.owns(dataId)) throw new Error('Not owner');
// ... more checks ...
await database.delete(dataId);
}
// After: Phantom handles everything
@Phantom.Protect({
intent: 'data_deletion',
requiresOwnership: true
})
async function deleteUserData(userId: string, dataId: string) {
// If we reach here, all checks passed
await database.delete(dataId);
}from phantom import protect
@protect(intent="data_deletion", requires_ownership=True)
async def delete_user_data(user_id: str, data_id: str):
"""Phantom verifies permissions before execution"""
await database.delete(data_id)Shadow Sync keeps permissions in real-time sync with your database and billing systems.
import { PrismaClient } from '@prisma/client';
import { PhantomPrismaMiddleware } from '@vanishlabs/phantom';
const prisma = new PrismaClient().$extends(
PhantomPrismaMiddleware({
// Automatically sync ownership relationships
models: {
document: { ownerField: 'userId' },
project: { ownerField: 'creatorId' },
}
})
);
// Now every create/update/delete automatically updates Phantom's permission graph// Add this webhook endpoint to sync billing entitlements
import { Phantom } from '@vanishlabs/phantom';
export async function POST(req: Request) {
const signature = req.headers.get('stripe-signature');
const event = await stripe.webhooks.constructEvent(
await req.text(),
signature,
process.env.STRIPE_WEBHOOK_SECRET
);
// Phantom automatically handles subscription changes
await Phantom.stripe.processWebhook(event);
return new Response('OK');
}npm run phantom:test
# Or use the CLI
npx phantom test-mission \
--user-id "user_123" \
--intent "Test basic permissions" \
--action "read_data"Deep dive into Ghost Tokens, Shadow Sync, Intent-Aware Reasoning, and Durable Missions.
Complete API documentation for all SDK methods and configuration options.
Learn about our "invisible" approach to security and the future of agentic authorization.