Public API Documentation (EN)

Capt’n Boat Public API Documentation

The Capt’n Boat public API allows you to send the creation of a job request directly to the Capt’n Boat commercial team.

To do so, you need to:

  1. Create a boat
  2. Create an ad (mission)
  3. Create a job
  4. Provide your client’s billing information

The commercial team will then contact your client to finalize the booking of the Seaman (Skipper / Hostess…) and send the payment link, invoice, and contract by email.

API Objectives

The public API opens certain platform functionalities to external partners, allowing them to publish Capt’n Boat ads directly from their own systems. It allows you to:

  • Register boats
  • Create ads (an ad corresponds to a specific mission for a boat and may include several jobs)
  • Create job postings (positions)
  • Cancel a request
  • Retrieve contact information for the assigned seaman

The API is not designed to manage or edit boats and ads; this is handled in the Capt’n Boat user interface.

Technical Implementation

The external API is a GraphQL API. Access is restricted to users who have been issued a token by Capt’n Boat.

  • Endpoint: https://api-int.captnboat.com/opengraphql
  • Authentication: header x-api-key: <YOUR_TOKEN>
curl 'https://api-int.captnboat.com/opengraphql' \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: <YOUR_TOKEN>' \
  -d '{"query":"{ __typename }"}'
⚠️

Each request must include the x-api-key header.


Available Queries

List Flags

To associate a boat with a flag.

query Flags {
  listFlags {
    nodes {
      id
      name
    }
  }
}

Example (cURL)

curl 'https://api-int.captnboat.com/opengraphql' \
  -X POST \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: <YOUR_TOKEN>' \
  -d '{"query":"{listFlags{nodes{id name}}}"}'

Matching Skippers

Used to estimate the number of skippers who have the required licenses and availability for a given period.

💡

This list is not the list of skippers who applied: it only shows eligible skippers (they may not be interested or may ask for a higher salary).

Query

query Correspondants {
  skipperCorrespondant(
    pAdType: DELIVERY
    pBoatCommercialUsage: false
    pBoatCountryId: "ef08f160-9858-464b-9e59-a93f94ad5260"
    pBoatType: SAILBOAT
    pCoastDistance: 25
    pCommercialActivity: false
    pStartHarborLatitude: 47.27991613225704
    pStartHarborLongitude: -2.1976906604134157
    pEndHarborLatitude: 47.27991613225704
    pEndHarborLongitude: -2.1976906604134157
    pBeam: 4.5
    pHullLength: 20
    pPassengerNumber: 10
    pIsCaptain: false
    pPosition: SKIPPER
    pStartDate: "2026-06-15"
    pEndDate: "2026-06-30"
  ) {
    totalCount
    nodes {
      firstName
      civility
      birthday
      nationality
      averageNotations
      cv
      documents
      sailorAvatar
    }
  }
}

Payload (arguments)

  • pAdType: AdTypeEnum! — type of job (DELIVERY, CHARTER, COACHING, …)
  • pBoatCommercialUsage: Boolean! — whether the boat is used commercially
  • pBoatCountryId: UUID! — boat’s flag/country
  • pBoatType: BoatTypeEnum!MOTORBOAT | SAILBOAT | MULTIHULL
  • pCoastDistance: Int — maximum distance from the coast (NM)
  • pCommercialActivity: Boolean! — whether commercial activity is expected
  • pStartHarborLatitude: Float!
  • pStartHarborLongitude: Float!
  • pEndHarborLatitude: Float!
  • pEndHarborLongitude: Float!
  • pBeam: Float! — width (m)
  • pHullLength: Float! — hull length (m)
  • pPassengerNumber: Int!
  • pIsCaptain: Boolean! — need for a captain
  • pPosition: PositionEnum! — e.g. SKIPPER, FIRST_MATE, …
  • pStartDate: Date! — ISO format (YYYY-MM-DD)
  • pEndDate: Date! — ISO format (YYYY-MM-DD)

Fields returned

  • totalCount: Int! — number of matching skippers
  • nodes[].firstName: String
  • nodes[].civility: CivilityEnumMALE | FEMALE
  • nodes[].birthday: DateTime
  • nodes[].nationality: String
  • nodes[].averageNotations: Float — average note
  • nodes[].cv: String — CV URL
  • nodes[].documents: [String!]! — licenses and certificates
  • nodes[].sailorAvatar: String — Picture

Example result

{
  "data": {
    "skipperCorrespondant": {
      "totalCount": 1,
      "nodes": [
        {
          "firstName": "Charles",
          "civility": "MALE",
          "birthday": "1998-07-14T00:00:00Z",
          "nationality": "French",
          "averageNotations": 4.2,
          "cv": "https://cellar-c2.services.clever-cloud.com/captn-int/b3qu09dl1_CV_pull1.PNG",
          "documents": [
            "BE VOILE",
            "CAPTAIN",
            "CFBS",
            "Human Safety & Social Responsibility Training (SPRS)",
            "GMDSS GOC / CGO",
            "MEDICAL VISIT"
          ],
          "sailorAvatar": "https://cellar-c2.services.clever-cloud.com/captn-dev/tthj05mz6_capitain_iglo.jpg"
        }
      ]
    }
  }
}

Register a Boat

Creates (or retrieves) a boat. If an identical boat already exists, the mutation will not create a duplicate and will simply return its id.

mutation CreateBoat {
  createBoat(
    input: {
      name: "testBoat3"
      flagId: "ef08f160-9858-464b-9e59-a93f94ad5260"
      boatPictures: ["http://mypictures.com/myboat.jpg"]
      boatType: MOTORBOAT
      builderName: "Jo Boats"
      enginePower: 10
      hullLength: 15
      beam: 4
      hullType: MONOHULL
      modelName: "Jo Boat 1"
      registrationNumber: "registration"
      hasAutopilot: true
    }
  ) {
    boat { id }
  }
}

Payload (CreateBoatInput)

  • name: String!
  • flagId: UUID!
  • boatPictures: [String!]
  • boatType: BoatTypeEnum!MOTORBOAT | SAILBOAT | MULTIHULL
  • builderName: String!
  • enginePower: Int
  • hullLength: Float!
  • beam: Float!
  • hullType: HullTypeEnum!MONOHULL | CATAMARAN | TRIMARAN
  • modelName: String!
  • registrationNumber: String
  • hasAutopilot: Boolean

Example result

{
  "data": {
    "createBoat": { "boat": { "id": "b408c93b-74a7-4d67-9fdd-a61f764e2284" } }
  }
}

Create an Ad (Mission)

Creates a mission (trip, ports, and dates) for a boat.

mutation CompleteAd {
  createCompleteAd(
    input: {
      adType: CHARTER
      boatId: "b408c93b-74a7-4d67-9fdd-a61f764e2284"
      startDate: "2025-06-01"
      endDate: "2025-06-15"
      spokenLanguage: ["245e9757-a9ab-4fd8-af33-f99498d5d3ef"]
      startHarborLatitude: 47.27991613225704
      startHarborLongitude: -2.1976906604134157
      endHarborLatitude: 47.27991613225704
      endHarborLongitude: -2.1976906604134157
      passengerNumber: 10
      commercialActivity: false
      description: "Sample description"
    }
  ) {
    ad { id }
  }
}

Payload (CreateCompleteAdInput)

  • boatId: UUID!
  • startDate: DateTime! / endDate: DateTime!
  • startHarborLatitude/Longitude: Float!
  • endHarborLatitude/Longitude: Float!
  • adType: AdTypeEnum! — e.g. CHARTER, COACHING, DELIVERY
  • passengerNumber: Int
  • description: String
  • commercialActivity: Boolean
  • spokenLanguage: [UUID]!

Get available languages:

query Languages {
  languages { nodes { id name } }
}

Example result

{
  "data": {
    "createCompleteAd": { "ad": { "id": "2c2bf016-5604-4e71-bf81-3a1e7399ee9d" } }
  }
}

Create a Job

Estimate Compensation

query Price {
  estimatedPrice(
    adType: CHARTER
    startDate: "2025-08-08"
    endDate: "2025-08-15"
    startHarborLatitude: 47.27991613225704
    startHarborLongitude: -2.1976906604134157
    endHarborLatitude: 47.27991613225704
    endHarborLongitude: -2.1976906604134157
    hullLength: 15
    positionType: SKIPPER
  )
}

Payload

  • startDate: Date! / endDate: Date!
  • startHarborLatitude/Longitude: Float!
  • endHarborLatitude/Longitude: Float!
  • adType: AdTypeEnum!CHARTER | SUPPORT | COACHING
  • hullLength: Float!
  • positionType: PositionEnum!SKIPPER, HOSTESS, DECKHAND, FIRST_MATE, CHEF, ENGINEER, WATCH_LEADER

Example result

{ "data": { "estimatedPrice": 2360 } }

Create the job

mutation CompleteJob {
  createCompleteJob(
    input: {
      adId: "20ca3ae7-a1c0-4bba-984f-0a9c952f7207"
      positionType: SKIPPER
      price: 2360
      travelFee: OWNER
      reserved: FAVOURITES
      referenceId: "12"
 
      billingFirstname: "Jo"
      billingLastname: "Durand"
      billingEmail: "billing@myemail.com"
      billingPhoneNumber: "1234567890"
      billingDateOfBirth: "2000-01-01"
      billingLanguage: "fr"
      billingSiret: "1234567890"
      billingRegistrationNumber: "ag-y78hn5"
 
      billingAddressFirstLine: "52 rue Truffaut"
      billingAddressZipCode: "75017"
      billingAddressCityName: "Paris"
      billingAddressCountry: "FR"
 
      lessor: ""
    }
  ) {
    job { id }
  }
}

Payload (CreateCompleteJobInput)

  • References

    • adId: UUID!
    • referenceId: String — to link your internal record with the Capt’n Boat job
  • Job details

    • positionType: PositionEnum!
    • price: Float!
    • travelFee: TravelFeeEnumOWNER | SKIPPER | NEGOTIABLE
    • reserved: ReservedEnumALL | APPROVED | FAVOURITES | RESERVED
  • Billing (client)

    • billingFirstname, billingLastname, billingEmail, billingPhoneNumber, billingDateOfBirth
    • billingLanguage, billingSiret, billingRegistrationNumber
    • billingAddressFirstLine, billingAddressZipCode, billingAddressCityName, billingAddressCountry
  • Other

    • lessor: String

Example result

{
  "data": {
    "createCompleteJob": { "job": { "id": "636301f5-6c31-4d20-88c6-4eb8ddd81382" } }
  }
}

Cancel a Job

mutation CancelJob {
  cancelJob(
    input: {
      reason: DELAYED
      jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
      referenceId: "12"
    }
  ) {
    job { id }
  }
}

Payload (CancelJobInput)

  • reason: CancelReasonEnumFOUND, DELAYED, NOT_FOUND, ERROR, DUPLICATE, CONTACT, OTHER
  • jobId: UUID
  • referenceId: String

Example result

{
  "data": {
    "cancelJob": { "job": { "id": "636301f5-6c31-4d20-88c6-4eb8ddd81382" } }
  }
}

Seamen Offers

List all offers made by seamen for a given job.

query Offers {
  jobOffers(
    jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
    referenceId: "12"
  ) {
    captnBoatProfil
    firstName
    isCaptnBoatApprooved
    isFavoris
    picture
    price
    travelFee
    urlSignature
  }
}

Arguments

  • jobId: UUID
  • referenceId: String

Example result

{
  "data": {
    "jobOffers": [
      {
        "captnBoatProfil": "https://captnboat.com/skippers/123",
        "firstName": "Marie",
        "isCaptnBoatApprooved": true,
        "isFavoris": false,
        "picture": "https://…/avatar.jpg",
        "price": 2450,
        "travelFee": 150,
        "urlSignature": "https://…/offer/123/sign"
      }
    ]
  }
}

Seaman Contact

Available after payment. Returns contact and contract information.

query Contact {
  sailorContact(
    jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
    referenceId: "12"
  ) {
    firstName
    lastName
    email
    phoneNumber
    civility
    birthday
    birthPlace
    birthCountry
    nationality
    price
    travelFee
    degree
    contract
    invoices
    address
  }
}

Arguments

  • jobId: UUID
  • `referenceId