← スキル一覧に戻る

tripit-export
by caseyg
Casey's Claude skills and other config
⭐ 0🍴 0📅 2026年1月19日
SKILL.md
name: tripit-export description: Export TripIt travel data (trips, flights, hotels) to JSON using browser automation. Use when the user asks to export, download, or backup their TripIt data.
TripIt Export
Export all TripIt travel data (trips, flights, lodging, activities) to JSON format using TripIt's undocumented API v2.
Trigger Phrases
- "export tripit data"
- "export my trips from tripit"
- "download tripit trips"
/tripit-export
Prerequisites
- dev-browser plugin: Browser automation with persistent state
- TripIt account: User must be able to log in to tripit.com
API Reference
Discovered Endpoints
# List upcoming trips (paginated)
GET /api/v2/list/trip?exclude_types=weather&page_size=50&past=false&traveler=true&page_num=1
# List past trips (paginated)
GET /api/v2/list/trip?exclude_types=weather&page_size=50&past=true&traveler=all&page_num=1
# Get full trip details (includes flights, lodging, activities)
GET /api/v2/get/trip/uuid/{trip-uuid}/include_objects/true?exclude_types=weather
# User profile
GET /api/v2/get/profile
Response Structure
Trip List Response:
{
"timestamp": "...",
"page_num": "1",
"page_size": "50",
"max_page": "1",
"Trip": [...]
}
Trip Details Response:
{
"Trip": {...},
"AirObject": [...],
"LodgingObject": [...],
"ActivityObject": [...],
"CarObject": [...],
"RestaurantObject": [...],
"NoteObject": [...],
"TransportObject": [...],
"RailObject": [...],
"CruiseObject": [...]
}
Workflow
Step 1: Launch Browser and Authenticate
Navigate to TripIt and have the user log in:
import { connect, waitForPageLoad } from "@/client.js";
const client = await connect("http://127.0.0.1:9222");
const page = await client.page("tripit");
await page.goto("https://www.tripit.com/app/trips");
await waitForPageLoad(page);
console.log("Please log in to TripIt...");
Tell user to log in manually, then confirm when done.
Step 2: Fetch All Trips
After authentication, fetch upcoming and past trips with pagination:
async function fetchAllTrips(page, past: boolean): Promise<any[]> {
const allTrips: any[] = [];
let pageNum = 1;
let maxPage = 1;
do {
const params = new URLSearchParams({
exclude_types: "weather",
page_size: "50",
past: String(past),
traveler: past ? "all" : "true",
page_num: String(pageNum)
});
const response = await page.evaluate(async (url) => {
const res = await fetch(url, {
headers: { "Accept": "application/json" }
});
return res.json();
}, `/api/v2/list/trip?${params}`);
if (response.Trip) {
const trips = Array.isArray(response.Trip) ? response.Trip : [response.Trip];
allTrips.push(...trips);
}
maxPage = parseInt(response.max_page || "1");
pageNum++;
} while (pageNum <= maxPage);
return allTrips;
}
const upcomingTrips = await fetchAllTrips(page, false);
const pastTrips = await fetchAllTrips(page, true);
Step 3: Fetch Full Trip Details
For each trip, fetch complete details:
const tripDetails = {};
for (const trip of [...upcomingTrips, ...pastTrips]) {
const details = await page.evaluate(async (uuid) => {
const res = await fetch(
`/api/v2/get/trip/uuid/${uuid}/include_objects/true?exclude_types=weather`,
{ headers: { "Accept": "application/json" } }
);
return res.json();
}, trip.uuid);
tripDetails[trip.uuid] = {
trip: details.Trip,
flights: details.AirObject || [],
lodging: details.LodgingObject || [],
activities: details.ActivityObject || [],
cars: details.CarObject || [],
restaurants: details.RestaurantObject || [],
notes: details.NoteObject || [],
transport: details.TransportObject || [],
rail: details.RailObject || [],
cruise: details.CruiseObject || []
};
// Rate limiting
await page.waitForTimeout(500);
}
Step 4: Generate Final Export
const exportData = {
exportDate: new Date().toISOString(),
summary: {
upcomingTrips: upcomingTrips.length,
pastTrips: pastTrips.length,
totalTrips: upcomingTrips.length + pastTrips.length
},
trips: Object.entries(tripDetails).map(([uuid, details]) => ({
uuid,
name: details.trip?.display_name,
startDate: details.trip?.start_date,
endDate: details.trip?.end_date,
primaryLocation: details.trip?.primary_location,
...details
}))
};
const outputPath = `tripit-export-${new Date().toISOString().split("T")[0]}.json`;
writeFileSync(outputPath, JSON.stringify(exportData, null, 2));
Output Format
{
"exportDate": "2026-01-13T...",
"summary": {
"upcomingTrips": 2,
"pastTrips": 45,
"totalTrips": 47
},
"trips": [
{
"uuid": "...",
"name": "Trip Name",
"startDate": "2026-01-15",
"endDate": "2026-01-20",
"primaryLocation": "Tokyo, Japan",
"trip": { /* full trip metadata */ },
"flights": [ /* AirObject array */ ],
"lodging": [ /* LodgingObject array */ ],
"activities": [ /* ActivityObject array */ ],
"cars": [],
"restaurants": [],
"notes": [],
"transport": [],
"rail": [],
"cruise": []
}
]
}
Error Handling
- 401 Unauthorized: Session expired. Re-authenticate by navigating to TripIt login.
- Rate limiting: Add delays between API calls if receiving 429 errors.
- Empty responses: Some trips may have no flights/lodging - this is normal.
Notes
- TripIt API v2 is undocumented and may change without notice
- Authentication is session-based (cookies) - no API key required
- Large trip histories may take several minutes to export
- The
exclude_types=weatherparam reduces response size
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です