Marvin · Developers

Offres et candidatures

Lire les offres publiées d'un client et y déposer des candidatures avec CV

Ce guide s'adresse aux outils de sourcing et de préqualification qui envoient des candidats sur les offres d'un client Marvin. Deux appels suffisent : lire les offres que le client publie sur son site carrière, puis déposer une candidature sur l'une d'elles.

La candidature arrive dans l'onglet Candidatures de l'offre, où le recruteur la traite comme une candidature reçue sur son site carrière. Le CV est analysé et le profil du candidat rattaché ou créé.

Clé d'API

L'administrateur du client génère la clé depuis Paramètres → Intégrations, sur la page du connecteur de votre outil, puis vous la transmet avec l'identifiant de son compte ({slug}).

  • C'est une clé partenaire, générée par un connecteur prévu pour ces routes : partner:projects:read ouvre la lecture des offres, partner:candidates:write le dépôt des candidatures. Toutes les clés partenaires ne les ouvrent pas — en cas de 403, vérifiez avec Marvin que votre connecteur est bien celui-ci.
  • Elle s'envoie uniquement dans le header X-Marvin-Public-Key. Passée dans l'URL (?key=), elle est refusée (401).
  • C'est un secret côté serveur : ne l'exposez jamais dans du code exécuté par un navigateur.
X-Marvin-Public-Key: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Lire les offres

GET https://api.marvins.ai/v1/public/careers/{slug}/feed.xml

Le flux liste les offres publiées sur le site carrière du client : ce sont les seules sur lesquelles une candidature peut être déposée. Chaque offre est un élément <job>, dont <id> est l'identifiant à utiliser pour le dépôt.

curl "https://api.marvins.ai/v1/public/careers/{slug}/feed.xml" \
  -H "X-Marvin-Public-Key: pk_live_…"

La même liste existe en JSON : GET https://api.marvins.ai/v1/public/careers/{slug}.

Les erreurs du flux sont au format XML (<error><code>…</code><message>…</message></error>) : 401 et 403 comme ci-dessous. Un slug qui n'est pas celui du client de la clé renvoie 403 slug_mismatch.

Déposer une candidature

POST https://api.marvins.ai/v1/public/careers/{slug}/jobs/{jobId}/apply

où {jobId} est l'<id> de l'offre lu dans le flux. Le corps s'envoie en multipart/form-data (pour joindre le CV) ou en application/json.

ChampTypeRequisDescription
firstNamestringouiPrénom (100 caractères max.)
lastNamestringouiNom (100 caractères max.)
emailstringouiE-mail du candidat
phoneNumberstringnonTéléphone
linkedinstringnonURL du profil LinkedIn
motivationTextstringnonMessage, notes de préqualification (5 000 caractères max.)
resumefilenonCV (resume ou cv), en multipart
champs perso—nonChamps personnalisés du formulaire du client

firstName, lastName ou email manquant ou invalide renvoie 400. Le client peut rendre d'autres champs obligatoires dans son formulaire de candidature : un tel champ manquant renvoie 422, avec son nom dans error.field.

CV : PDF, DOC, DOCX, JPEG, PNG, WEBP ou GIF, 10 Mo maximum (au-delà : 413).

Provenance : elle est fixée par la clé. La candidature et le candidat sont attribués à votre outil, sans paramètre à passer.

Doublons : une candidature pour une offre où le même e-mail a déjà une candidature active est acceptée (201) et mise en quarantaine pour arbitrage par le recruteur. Aucun profil en double n'est créé.

curl -X POST \
  "https://api.marvins.ai/v1/public/careers/{slug}/jobs/{jobId}/apply" \
  -H "X-Marvin-Public-Key: pk_live_…" \
  -F "firstName=Marie" \
  -F "lastName=Dupont" \
  -F "email=marie.dupont@example.com" \
  -F "motivationText=Disponible sous un mois, prétentions 45 k€." \
  -F "resume=@/chemin/vers/cv.pdf"

Candidature spontanée

Pour un candidat qui ne vise aucune offre : POST https://api.marvins.ai/v1/public/careers/{slug}/apply, avec les mêmes champs.

Réponses

Succès : 201 avec l'identifiant de la candidature, { "data": { "id": "…" } }.

Les erreurs du dépôt ont la forme { "error": { "code": "…", "message": "…" } } ({ "error": { "code": "…", "field": "…" } } pour un 422). Testez le code, qui est stable.

StatutcodeCas
400validation_errorChamp obligatoire manquant ou invalide, type de fichier refusé
401unauthorizedClé absente, malformée, révoquée, ou clé partenaire passée dans l'URL
403insufficient_scopeDroit manquant sur la clé — le message nomme le scope manquant
403slug_mismatchLecture du flux : slug d'un autre client que la clé
404job_not_foundOffre inconnue, ou dépôt avec le slug d'un autre client que la clé
410job_removedOffre fermée, dépubliée ou supprimée
413—CV trop lourd (plus de 10 Mo) — testez le statut, pas le code
422missing_required_fieldChamp rendu obligatoire par le client — error.field nomme le champ
429rate_limitedTrop de dépôts (30 par minute et par clé)

Bonnes pratiques

  • Relisez le flux avant d'envoyer : une offre fermée ou dépubliée renvoie 410.
  • Envoyez le CV quand vous l'avez : c'est lui qui remplit le profil du candidat.
  • Mettez vos notes de préqualification dans motivationText : le recruteur les lit sur la candidature.

Pour les schémas complets, voir la Référence API — Careers (Public).

On this page