Guide d'utilisation de l'API PDP
Plateforme de Dématérialisation PartenaireCopied!
Table des matières
IntroductionCopied!
L'API PDP (Plateforme de Dématérialisation Partenaire) permet aux organisations de gérer leurs documents numériques, workflows de validation et signatures électroniques de manière sécurisée et conforme aux réglementations françaises.
Caractéristiques principales
-
Sécurité renforcée : Authentification JWT, audit trail complet
-
Conformité réglementaire : Respect des normes françaises de dématérialisation
-
Signatures électroniques : Support des signatures simples, avancées et qualifiées
-
Workflows flexibles : Processus de validation configurables
-
API REST : Interface standardisée et bien documentée
Prérequis
-
Compte partenaire validé sur la plateforme PDP
-
Clés d'API fournies par l'équipe PDP
-
Connaissance des API REST et du format JSON
Premiers pasCopied!
1. Environnements disponibles
|
Environnement |
URL |
Usage |
|---|---|---|
|
Production |
|
Utilisation en production |
|
Test |
|
Tests et développement |
2. Authentification initiale
Toutes les requêtes nécessitent une authentification. Utilisez vos identifiants partenaire pour obtenir un token :
j3. Utilisation du token
Incluez le token dans l'en-tête
Authorization
de toutes vos requêtes :
AuthentificationCopied!
Types d'authentification
L'API supporte deux méthodes d'authentification :
-
JWT Bearer Token (recommandé) : Token temporaire avec refresh automatique
-
API Key : Clé permanente pour les intégrations serveur-à-serveur
Gestion des tokens JWT
Les tokens JWT ont une durée de vie limitée (1 heure par défaut). Utilisez le refresh token pour renouveler automatiquement :
Sécurité
-
Stockage sécurisé : Ne jamais exposer les tokens côté client
-
HTTPS obligatoire : Toutes les communications doivent utiliser HTTPS
-
Rotation régulière : Les clés d'API doivent être renouvelées périodiquement
Gestion des documentsCopied!
Upload d'un document
L'upload utilise le format
multipart/form-data
pour supporter les fichiers binaires :
Types de documents supportés
|
Type |
Description |
Métadonnées spécifiques |
|---|---|---|
|
|
Factures et notes de frais |
|
|
|
Contrats et avenants |
|
|
|
Devis et propositions commerciales |
|
|
|
Bons de commande |
|
|
|
Autres types de documents |
Métadonnées libres |
Recherche et filtrage
Gestion des versions
Chaque modification d'un document crée une nouvelle version. L'historique complet est conservé :
Workflows de validationCopied!
Types de workflows
-
Validation simple : Un seul validateur
-
Validation multiple : Plusieurs validateurs en séquence
-
Signature électronique : Processus de signature multi-parties
Création d'un workflow
Exécution d'un workflow
Suivi de l'exécution
L'API fournit un suivi en temps réel de l'avancement :
Signatures électroniquesCopied!
Types de signatures supportés
|
Type |
Niveau de sécurité |
Usage recommandé |
|---|---|---|
|
|
Basique |
Documents internes, accusés de réception |
|
|
Élevé |
Contrats commerciaux, documents officiels |
|
|
Maximum |
Documents juridiques, actes notariés |
Processus de signature
1. Création de la demande
2. Notification des signataires
Les signataires reçoivent automatiquement :
-
Email avec lien de signature sécurisé
-
Token de signature unique
-
Instructions de signature
3. Processus de signature
Validation des signatures
Toutes les signatures incluent :
-
Certificat numérique : Identité du signataire
-
Horodatage qualifié : Date et heure exactes
-
Empreinte du document : Garantie d'intégrité
-
Adresse IP : Traçabilité géographique
NotificationsCopied!
Types de notifications
|
Type |
Description |
Déclencheur |
|---|---|---|
|
|
Nouveau document reçu |
Upload de document |
|
|
Signature demandée |
Création demande de signature |
|
|
Workflow terminé |
Fin de processus |
|
|
Erreur système |
Échec d'opération |
Consultation des notifications
Webhooks (optionnel)
Pour un traitement en temps réel, configurez des webhooks :
Audit et traçabilitéCopied!
Consultation des logs
L'API fournit un accès complet aux logs d'audit :
Informations tracées
Chaque action inclut :
-
Qui : Utilisateur ayant effectué l'action
-
Quoi : Type d'action et ressource concernée
-
Quand : Horodatage précis
-
Où : Adresse IP et user agent
-
Détails : Informations contextuelles
Conformité RGPD
-
Pseudonymisation des données personnelles
-
Droit à l'effacement respecté
-
Durée de conservation configurable
-
Export des données sur demande
Codes d'erreurCopied!
Codes HTTP standards
|
Code |
Signification |
Action recommandée |
|---|---|---|
|
|
Succès |
Continuer |
|
|
Créé avec succès |
Continuer |
|
|
Requête invalide |
Vérifier les paramètres |
|
|
Non autorisé |
Renouveler le token |
|
|
Accès interdit |
Vérifier les permissions |
|
|
Non trouvé |
Vérifier l'ID de ressource |
|
|
Erreur de validation |
Corriger les données |
|
|
Trop de requêtes |
Implementer rate limiting |
|
|
Erreur serveur |
Réessayer plus tard |
Codes d'erreur métier
{
"code": "DOCUMENT_SIGNATURE_REQUIRED",
"message": "Ce document nécessite une signature avant validation",
"details": ["Le workflow exige une signature électronique"],
"timestamp": "2025-05-28T10:30:00Z"
}
Gestion des erreurs
async function handleApiCall(url, options) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 401:
// Renouveler le token
await refreshToken();
return handleApiCall(url, options);
case 422:
// Erreur de validation
console.error('Données invalides:', error.details);
break;
case 429:
// Rate limiting
await delay(error.retry_after * 1000);
return handleApiCall(url, options);
default:
console.error('Erreur API:', error.message);
}
throw new Error(error.message);
}
return await response.json();
} catch (error) {
console.error('Erreur réseau:', error);
throw error;
}
}
Exemples d'intégrationCopied!
Ruby on Rails
# Gemfile
gem 'faraday'
gem 'jwt'
# app/services/pdp_service.rb
class PdpService
BASE_URL = 'https://api.pdp.gouv.fr/v1'
def initialize(token = nil)
@token = token || authenticate
@client = Faraday.new(url: BASE_URL) do |conn|
conn.request :json
conn.response :json
conn.headers['Authorization'] = "Bearer #{@token}"
end
end
def upload_document(file_path, metadata)
payload = {
fichier: Faraday::UploadIO.new(file_path, 'application/pdf'),
type_document: metadata[:type],
titre: metadata[:titre],
description: metadata[:description]
}
response = @client.post('/documents', payload)
handle_response(response)
end
def create_signature_request(document_id, signataires)
payload = {
document_id: document_id,
type_signature: 'avancee',
signataires: signataires
}
response = @client.post('/signatures', payload)
handle_response(response)
end
private
def authenticate
response = Faraday.post("#{BASE_URL}/auth/login", {
email: ENV['PDP_EMAIL'],
mot_de_passe: ENV['PDP_PASSWORD'],
code_partenaire: ENV['PDP_PARTNER_CODE']
}.to_json, { 'Content-Type' => 'application/json' })
JSON.parse(response.body)['access_token']
end
def handle_response(response)
case response.status
when 200..299
response.body
when 401
@token = authenticate
raise 'Token expired, please retry'
else
raise "API Error: #{response.body['message']}"
end
end
end
# Utilisation
pdp = PdpService.new
# Upload d'un document
document = pdp.upload_document(
'/path/to/facture.pdf',
{
type: 'facture',
titre: 'Facture Mai 2025',
description: 'Facture de prestations'
}
)
# Demande de signature
signature = pdp.create_signature_request(
document['id'],
[
{
email: 'directeur@entreprise.fr',
nom: 'Dupont',
prenom: 'Jean',
ordre_signature: 1
}
]
)
JavaScript/Node.js
// package.json dependencies
// "axios": "^1.0.0",
// "form-data": "^4.0.0"
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
class PDPClient {
constructor() {
this.baseURL = 'https://api.pdp.gouv.fr/v1';
this.token = null;
this.client = axios.create({
baseURL: this.baseURL,
timeout: 30000
});
// Intercepteur pour l'authentification automatique
this.client.interceptors.request.use(async (config) => {
if (!this.token) {
await this.authenticate();
}
config.headers.Authorization = `Bearer ${this.token}`;
return config;
});
// Intercepteur pour le renouvellement automatique
this.client.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response?.status === 401) {
await this.authenticate();
return this.client.request(error.config);
}
return Promise.reject(error);
}
);
}
async authenticate() {
try {
const response = await axios.post(`${this.baseURL}/auth/login`, {
email: process.env.PDP_EMAIL,
mot_de_passe: process.env.PDP_PASSWORD,
code_partenaire: process.env.PDP_PARTNER_CODE
});
this.token = response.data.access_token;
return this.token;
} catch (error) {
throw new Error(`Authentication failed: ${error.message}`);
}
}
async uploadDocument(filePath, metadata) {
const form = new FormData();
form.append('fichier', fs.createReadStream(filePath));
form.append('type_document', metadata.type);
form.append('titre', metadata.titre);
if (metadata.description) {
form.append('description', metadata.description);
}
const response = await this.client.post('/documents', form, {
headers: form.getHeaders()
});
return response.data;
}
async getDocuments(filters = {}) {
const params = new URLSearchParams(filters);
const response = await this.client.get(`/documents?${params}`);
return response.data;
}
async createWorkflow(workflowData) {
const response = await this.client.post('/workflows', workflowData);
return response.data;
}
async executeWorkflow(workflowId, documentId, params = {}) {
const response = await this.client.post(`/workflows/${workflowId}/executer`, {
document_id: documentId,
parametres: params
});
return response.data;
}
}
// Utilisation
async function example() {
const pdp = new PDPClient();
try {
// Upload d'un document
const document = await pdp.uploadDocument('./facture.pdf', {
type: 'facture',
titre: 'Facture Mai 2025',
description: 'Prestations de développement'
});
console.log('Document uploadé:', document.id);
// Création d'un workflow
const workflow = await pdp.createWorkflow({
nom: 'Validation facture',
type_workflow: 'validation_simple',
etapes: [{
ordre: 1,
nom: 'Validation comptable',
type_action: 'validation',
assignes: ['comptable@entreprise.fr'],
delai_max: 48
}]
});
// Exécution du workflow
const execution = await pdp.executeWorkflow(
workflow.id,
document.id,
{ priorite: 'normale' }
);
console.log('Workflow lancé:', execution.id);
} catch (error) {
console.error('Erreur:', error.message);
}
}