Atlas / Skills / borski / Duffel

DuffelCAUTION

skills/borski/duffel

AI-powered travel hacking and search with cash, points, miles, and award flights. Drop-in skills and MCP servers for Claude, Codex, and OpenCode.

Verdict
CAUTION
Grade
B
Trust score
89 /100
Version
—
Hosts
—
License
MIT
Stars
693
01

Overview

AI-powered travel hacking and search with cash, points, miles, and award flights. Drop-in skills and MCP servers for Claude, Codex, and OpenCode.

Read from source at commit fda58ab480fdOBSERVED · 2026-10-14
Advertisement
02

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: duffel
description: Real-time GDS flight search via Duffel API. Accurate per-fare-class pricing, cabin selection, multi-city, time preferences. Primary cash price source. Does not include Southwest.
category: flights
summary: Primary cash prices. Real GDS per-fare-class data.
api_key: Duffel
allowed-tools: Bash(curl *)
---

# Duffel Flights

Search for real-time flight offers across airlines via the [Duffel API](https://duffel.com/docs/api). Returns live pricing, cabin details, baggage info, and booking links. Supports one-way, round-trip, and multi-city searches.

**Source:** [duffel.com](https://duffel.com)

## Prerequisites

- `DUFFEL_API_KEY_LIVE` environment variable set with a live API token
- Token needs `air.offer_requests.create` permission

## API Basics

- **Base URL:** `https://api.duffel.com`
- **Version header:** `Duffel-Version: v2` (REQUIRED, v1 is deprecated)
- **Auth:** `Authorization: Bearer $DUFFEL_API_KEY_LIVE`
- **Content-Type:** `application/json`
- **Rate limit:** 60 requests per 60 seconds

## Search Flights (One-Way)

```bash
curl -s -X POST "https://api.duffel.com/air/offer_requests?return_offers=true&supplier_timeout=15000" \
  -H "Accept: application/json" \
  -H "Duffel-Version: v2" \
  -H "Authorization: Bearer $DUFFEL_API_KEY_LIVE" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "slices": [{
        "origin": "SFO",
        "destination": "NRT",
        "departure_date": "2026-08-15"
      }],
      "passengers": [{"type": "adult"}],
      "cabin_class": "economy"
    }
  }'
```

## Search Flights (Round-Trip)

Add a second slice with origin/destination reversed:

```bash
curl -s -X POST "https://api.duffel.com/air/offer_requests?return_offers=true&supplier_timeout=15000" \
  -H "Accept: application/json" \
  -H "Duffel-Version: v2" \
  -H "Authorization: Bearer $DUFFEL_API_KEY_LIVE" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "slices": [
        {
          "origin": "SFO",
          "destination": "NRT",
          "departure_date": "2026-08-15"
        },
        {
          "origin": "NRT",
          "destination": "SFO",
          "departure_date": "2026-08-22"
        }
      ],
      "passengers": [{"type": "adult"}],
      "cabin_class": "business"
    }
  }'
```

## Search Flights (Multi-City)

Add as many slices as needed:

```bash
curl -s -X POST "https://api.duffel.com/air/offer_requests?return_offers=true&supplier_timeout=15000" \
  -H "Accept: application/json" \
  -H "Duffel-Version: v2" \
  -H "Authorization: Bearer $DUFFEL_API_KEY_LIVE" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "slices": [
        {"origin": "SFO", "destination": "NRT", "departure_date": "2026-08-15"},
        {"origin": "NRT", "destination": "ICN", "departure_date": "2026-08-20"},
        {"origin": "ICN", "destination": "SFO", "departure_date": "2026-08-25"}
      ],
      "passengers": [{"type": "adult"}],
      "cabin_class": "economy"
    }
  }'
```

## Nonstop Only

Set `max_connections` to 0:

```bash
curl -s -X POST "https://api.duffel.com/air/offer_requests?return_offers=true&supplier_timeout=15000" \
  -H "Accept: application/json" \
  -H "Duffel-Version: v2" \
  -H "Authorization: Bearer $DUFFEL_API_KEY_LIVE" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "slices": [{
        "origin": "SFO",
        "destination": "NRT",
        "departure_date": "2026-08-15"
      }],
      "passengers": [{"type": "adult"}],
      "cabin_class": "business",
      "max_connections": 0
    }
  }'
```

## Multiple Passengers

```json
"passengers": [
  {"type": "adult"},
  {"type": "adult"},
  {"age": 10},
  {"type": "infant_without_seat"}
]
```

Use `age` instead of `type` for children to avoid passenger type mismatches between search and booking.

## Time Preferences

Constrain departure or arrival times:

```json
"slices": [{
  "origin": "SFO",
  "destination": "NRT",
  "departure_date": "2026-08-15",
  "departure_time": {"from": "08:00", "to": "14:00"},
  "arrival_time": {"from": "06:00", "to": "18:00"}
}]
```

## Query Parameters

| Parameter | Default | Description |
|-----------|---------|-------------|
| `return_offers` | `true` | Set to `false` to get just the request ID, then fetch offers separately |
| `supplier_timeout` | `20000` | Max ms to wait for airline responses (2000 to 60000) |

## Reading the Response

The response is nested under `data`. Key fields:

```
data.id                              -> offer request ID
data.offers[]                        -> array of flight offers
  .id                                -> offer ID (use to get details or book)
  .total_amount / .total_currency    -> total price
  .base_amount / .base_currency      -> base fare (before tax)
  .tax_amount / .tax_currency        -> taxes
  .owner.name                        -> airline selling this
  .expires_at                        -> when offer expires
  .slices[]                          -> journey legs
    .origin.iata_code                -> departure airport
    .destination.iata_code           -> arrival airport
    .duration                        -> e.g. "PT11H30M"
    .segments[]                      -> individual flights
      .marketing_carrier.name        -> airline name
      .marketing_carrier_flight_number
      .operating_carrier.name        -> actual operating airline
      .departing_at / .arriving_at   -> datetime
      .duration                      -> segment duration
      .origin.iata_code / .destination.iata_code
      .passengers[].cabin_class      -> economy/business/first
      .passengers[].cabin.amenities  -> wifi, power, seat info
      .passengers[].baggages[]       -> checked/carry_on allowances
  .conditions                        -> refund/change policies
    .refund_before_departure.allowed
    .change_before_departure.allowed
    .change_before_departure.penalty_amount
```

## Get Offer Details

Retrieve full details for a specific offer:

```bash
03

Trust audit

CAUTIONgrade B · trust 89/100 Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (5)

MEDIUMInventory / provenance · inv.symlink · CWE-1104
.agents/skills
.agents/skills
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.claude/skills
.claude/skills
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
.opencode/skills
.opencode/skills
Why it matters. link not followed
MEDIUMInventory / provenance · inv.symlink · CWE-1104
skills
skills
Why it matters. link not followed
LOWInventory / provenance · inv.symlink · CWE-1104
AGENTS.md
AGENTS.md
Why it matters. link not followed

Gates applied: no_behavioural_pass.

Audited 2026-10-14 · audit v0.4.1 · source sha fda58ab480fdfull audit observations/trust-audit/skill/borski__duffel.json · Report an issue / request a re-scan
04

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-14fda58ab480fdCAUTIONB89first audit
05

Questions

What does the Duffel skill do?

AI-powered travel hacking and search with cash, points, miles, and award flights. Drop-in skills and MCP servers for Claude, Codex, and OpenCode.

Is Duffel safe to install?

With care. The audit graded it B (89/100) and found 5 things worth knowing before you trust this skill, listed below with the exact line each was found on.

What can Duffel access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

How current is this page?

The grade is for one exact copy of the source (fda58ab480fd), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement