Documentation API publique Capt’n Boat
L’API publique Capt’n Boat permet de transmettre la création d’un besoin à l’équipe commerciale Capt’n Boat.
Pour cela, il vous faut :
- Créer un bateau
- Créer une annonce (mission)
- Créer un poste (Job)
- Renseigner les informations de facturation
L’équipe commerciale contactera ensuite votre client pour finaliser la réservation du Marin (Skipper / Hôtesse…) et lui enverra lien de paiement, facture et contrat par e‑mail.
Objectifs de l’API
L’API publique ouvre certaines fonctionnalités de la plateforme à des intégrations externes pour publier des annonces Capt’n Boat depuis votre propre infrastructure. Elle permet notamment de :
- Enregistrer des navires
- Créer des annonces pour ces navires (une annonce correspond à une mission et peut comprendre plusieurs postes)
- Créer des fiches de poste (jobs)
- Annuler une demande
- Récupérer les informations de contact du marin retenu
L’API ne couvre pas la gestion complète des bateaux/annonces publiés : utilisez l’interface Capt’n Boat pour l’administration.
Implémentation technique
L’API externe est une API GraphQL. L’accès est restreint aux utilisateurs disposant d’un token fourni par Capt’n Boat.
- Endpoint :
https://api-int.captnboat.com/opengraphql - Authentification : header
x-api-key: <VOTRE_TOKEN>
curl 'https://api-int.captnboat.com/opengraphql' \
-X POST \
-H 'Content-Type: application/json' \
-H 'x-api-key: <VOTRE_TOKEN>' \
-d '{"query":"{ __typename }"}'Chaque requête doit inclure le header x-api-key.
Détail des requêtes disponibles
Lister les pavillons
Pour lier un navire à un pavillon.
query Flags {
listFlags {
nodes {
id
name
}
}
}Exemple cURL
curl 'https://api-int.captnboat.com/opengraphql' \
-X POST \
-H 'Content-Type: application/json' \
-H 'x-api-key: <VOTRE_TOKEN>' \
-d '{"query":"{listFlags{nodes{id name}}}"}'Skipper correspondant
Pour estimer le nombre de skippers ayant les diplômes requis et disponibles sur une période donnée.
Cette liste n’est pas la liste des candidats ayant postulé : ce sont des skippers éligibles (ils peuvent ne pas être intéressés ou demander une rémunération différente).
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
cv
documents
sailorAvatar
}
}
}Payload (arguments)
pAdType: AdTypeEnum!— type de mission (DELIVERY,CHARTER,COACHING, …)pBoatCommercialUsage: Boolean!— bateau exploité commercialementpBoatCountryId: UUID!— pavillon/pays du bateaupBoatType: BoatTypeEnum!—MOTORBOAT|SAILBOAT|MULTIHULLpCoastDistance: Int— distance max. à la côte (NM)pCommercialActivity: Boolean!— activité commerciale pendant la missionpStartHarborLatitude: Float!pStartHarborLongitude: Float!pEndHarborLatitude: Float!pEndHarborLongitude: Float!pBeam: Float!— largeur (m)pHullLength: Float!— longueur de coque (m)pPassengerNumber: Int!pIsCaptain: Boolean!— besoin d’un capitaine (responsable légal)pPosition: PositionEnum!—SKIPPER,HOTESSE, …pStartDate: Date!—YYYY-MM-DDpEndDate: Date!—YYYY-MM-DD
Sélection & retour
totalCount: Int!— nombre total de skippers éligiblesnodes[].firstName: Stringnodes[].civility: CivilityEnum—MALE|FEMALE| …nodes[].birthday: DateTimenodes[].nationality: Stringnodes[].averageNotations: FloatNotenodes[].cv: String— URL du CVnodes[].documents: [String!]!— diplômes/certificatsnodes[].sailorAvatar: String— Photo
Exemple de résultat
{
"data": {
"skipperCorrespondant": {
"totalCount": 1,
"nodes": [
{
"firstName": "Charles",
"civility": "MALE",
"birthday": "1998-07-14T00:00:00Z",
"nationality": "Française",
"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"
}
]
}
}
}Enregistrer un navire
Créer (ou récupérer) un bateau. Si un bateau identique existe déjà, la mutation ne recrée pas l’entrée et renvoie uniquement son 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|MULTIHULLbuilderName: String!enginePower: Int(HP)hullLength: Float!(m)beam: Float!(m)hullType: HullTypeEnum!—MONOHULL|CATAMARAN|TRIMARANmodelName: String!registrationNumber: StringhasAutopilot: Boolean
Résultat (exemple)
{
"data": {
"createBoat": { "boat": { "id": "b408c93b-74a7-4d67-9fdd-a61f764e2284" } }
}
}Créer une mission (Annonce)
Créer une mission (trajet + ports + dates) pour un bateau.
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: "Une description"
}
) {
ad { id }
}
}Payload (CreateCompleteAdInput)
boatId: UUID!startDate: DateTime!/endDate: DateTime!startHarborLatitude: Float!/startHarborLongitude: Float!endHarborLatitude: Float!/endHarborLongitude: Float!adType: AdTypeEnum!— valeurs usuelles :CHARTER,COACHING,DELIVERYpassengerNumber: Intdescription: StringcommercialActivity: BooleanspokenLanguage: [UUID]!— langues possibles :
query Languages {
languages { nodes { id name } }
}Résultat (exemple)
{
"data": {
"createCompleteAd": { "ad": { "id": "2c2bf016-5604-4e71-bf81-3a1e7399ee9d" } }
}
}Créer une fiche de poste (Job)
Estimation de rémunération
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|COACHINGhullLength: Float!positionType: PositionEnum!—SKIPPER,HOTESSE,MATELOT,SECOND,CHEF,MECANICIEN,CHEF_DE_QUART
Résultat (exemple)
{ "data": { "estimatedPrice": 2360 } }Création du 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)
-
Références
adId: UUID!referenceId: String— relier votre dossier interne au job Capt’n Boat
-
Poste
positionType: PositionEnum!— valeurs :SKIPPER,HOTESSE,MATELOT,SECOND,CHEF,MECANICIEN,CHEF_DE_QUARTprice: Float!travelFee: TravelFeeEnum—OWNER|SKIPPER|NEGOCIABLEreserved: ReservedEnum—ALL|APPROVED|FAVOURITES|RESERVED
-
Facturation (client)
billingFirstname: String!billingLastname: String!billingEmail: String!billingPhoneNumber: String!billingDateOfBirth: Date!billingLanguage: StringbillingRegistrationNumber: String!billingSiret: StringbillingAddressFirstLine: String!billingAddressZipCode: String!billingAddressCityName: String!billingAddressCountry: String!(code ISO 2)
-
Divers
lessor: String
Résultat (exemple)
{
"data": {
"createCompleteJob": { "job": { "id": "636301f5-6c31-4d20-88c6-4eb8ddd81382" } }
}
}Annuler une demande (Job)
mutation CancelJob {
cancelJob(
input: {
reason: DELAYED
jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
referenceId: "12"
}
) {
job { id }
}
}Payload (CancelJobInput)
reason: CancelReasonEnum—FOUND,DELAYED,NOT_FOUND,ERROR,DUPLICATE,CONTACT,OTHERjobId: UUIDreferenceId: String
Résultat (exemple)
{
"data": {
"cancelJob": { "job": { "id": "636301f5-6c31-4d20-88c6-4eb8ddd81382" } }
}
}Offres des marins
Lister les offres reçues pour un job.
query Offres {
jobOffers(
jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
referenceId: "12"
) {
captnBoatProfil
firstName
isCaptnBoatApprooved
isFavoris
picture
price
travelFee
urlSignature
}
}Arguments
jobId: UUIDreferenceId: String
Résultat (exemple)
{
"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"
}
]
}
}Contact du marin
Disponible après paiement. Retourne les informations nécessaires à la contractualisation.
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: UUIDreferenceId: String
Champs retournés
firstName, lastName, email, phoneNumber: Stringcivility: CivilityEnumbirthday: DateTimebirthPlace, birthCountry: Stringnationality: Stringprice, travelFee: Floatdegree, contract: Stringinvoices: [String]address: String
Résultat (exemple)
{
"data": {
"sailorContact": {
"firstName": "",
"lastName": "",
"email": "",
"phoneNumber": "",
"civility": "",
"birthday": "",
"birthPlace": "",
"birthCountry": "",
"nationality": "",
"price": 0,
"travelFee": 0,
"degree": "",
"contract": "",
"invoices": [],
"address": ""
}
}
}Note marin
Récupérer la note et le commentaire déposés par le client après la prestation.
query Notation {
jobNotation(
jobId: "636301f5-6c31-4d20-88c6-4eb8ddd81382"
referenceId: "12"
) {
notation
comment
}
}Arguments
jobId: UUIDreferenceId: String
Champs retournés
notation: Float(ouIntselon implémentation)comment: String
Résultat (exemple)
{
"data": {
"jobNotation": {
"notation": 4.8,
"comment": "Très bon skipper, communication fluide."
}
}
}Bonnes pratiques & validations
- Coordonnées : utilisez
Floatpour latitude/longitude (pas de strings). - Dates : format ISO 8601 (
YYYY-MM-DD/YYYY-MM-DDTHH:mm:ssZ). - Orthographe des champs :
nationality(pasnatinality),Latitude(un seul « t »),hasAutopilot(pasasAutopilot). - Idempotence : documentez les champs d’unicité de
createBoat(ex.registrationNumber+flagId). - Pagination/tri : exposez idéalement
first,offset,orderBysur les listes (ex.skipperCorrespondant).
Pour toute demande supplémentaire : api-ext@captnboat.com.