Transférer des fichiers
Déposer des fichiers volumineux par morceaux, les envoyer à des destinataires, puis suivre leurs téléchargements.
Un transfert envoie des fichiers à des personnes qui n'ont pas de compte : chacune reçoit un lien, protégé au besoin par un code ou un mot de passe, valable une durée choisie. Les fichiers ne passent pas par l'API : vous les déposez directement dans le stockage, par morceaux, à des adresses que l'API vous donne.
1Les bornes
GET https://staging-api.docage.com/Transfers/Limits : la taille totale permise, le nombre de fichiers et de destinataires, la taille d'un morceau, les
durées de vie possibles. Un compte d'essai a des bornes plus étroites.
2Le transfert
POST https://staging-api.docage.com/Transfers
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Name": "Plans de la vitrine — Atelier Lumière",
"Kind": 0,
"Mode": 0,
"Protection": 1,
"RetentionHours": 168,
"Message": "Bonjour Hugo, voici les plans validés.",
"NotifyOnDownload": true
}curl -X POST "https://staging-api.docage.com/Transfers" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Name": "Plans de la vitrine — Atelier Lumière",
"Kind": 0,
"Mode": 0,
"Protection": 1,
"RetentionHours": 168,
"Message": "Bonjour Hugo, voici les plans validés.",
"NotifyOnDownload": true
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Transfers");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Name": "Plans de la vitrine — Atelier Lumière",
"Kind": 0,
"Mode": 0,
"Protection": 1,
"RetentionHours": 168,
"Message": "Bonjour Hugo, voici les plans validés.",
"NotifyOnDownload": true
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Name": "Plans de la vitrine — Atelier Lumière",
"Kind": 0,
"Mode": 0,
"Protection": 1,
"RetentionHours": 168,
"Message": "Bonjour Hugo, voici les plans validés.",
"NotifyOnDownload": true
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Mode : 0 un email à chaque destinataire, 1 un lien commun à partager vous-même. Protection : 0 aucune, 1 un code envoyé
au destinataire, 2 un mot de passe (posé par PUT https://staging-api.docage.com/Transfers/{id}/Password). La réponse est l'identifiant du transfert.
3Déposer un fichier
POST https://staging-api.docage.com/Transfers/{id}/Files
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{ "Name": "plans-vitrine.pdf", "Size": 41943040 }curl -X POST "https://staging-api.docage.com/Transfers/{id}/Files" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{"Name": "plans-vitrine.pdf", "Size": 41943040}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Transfers/{id}/Files");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Name": "plans-vitrine.pdf",
"Size": 41943040
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers/{id}/Files", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({"Name": "plans-vitrine.pdf", "Size": 41943040})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;La réponse ouvre le dépôt : l'identifiant du fichier, la taille d'un morceau (PartSize) et leur nombre (PartCount). Demandez
les adresses des morceaux, valables dix minutes :
POST https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/PartUrls
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{ "PartNumbers": [1, 2, 3] }curl -X POST "https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/PartUrls" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{"PartNumbers": [1, 2, 3]}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/PartUrls");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"PartNumbers": [
1,
2,
3
]
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/PartUrls", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({"PartNumbers": [1, 2, 3]})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Envoyez chaque morceau par un PUT à son adresse, sans en-tête d'authentification, et gardez l'en-tête ETag de chaque réponse.
Puis fermez le dépôt :
POST https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/Complete
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{ "Parts": [ { "PartNumber": 1, "ETag": "\"9b2c…\"" }, { "PartNumber": 2, "ETag": "\"41fe…\"" }, { "PartNumber": 3, "ETag": "\"0d77…\"" } ] }curl -X POST "https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/Complete" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Parts": [{"PartNumber": 1, "ETag": "\"9b2c…\""}, {"PartNumber": 2, "ETag": "\"41fe…\""}, {"PartNumber": 3, "ETag": "\"0d77…\""}]
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/Complete");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Parts": [
{
"PartNumber": 1,
"ETag": "\"9b2c…\""
},
{
"PartNumber": 2,
"ETag": "\"41fe…\""
},
{
"PartNumber": 3,
"ETag": "\"0d77…\""
}
]
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/Complete", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Parts": [{"PartNumber": 1, "ETag": "\"9b2c…\""}, {"PartNumber": 2, "ETag": "\"41fe…\""}, {"PartNumber": 3, "ETag": "\"0d77…\""}]
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Après une coupure, GET https://staging-api.docage.com/Transfers/{id}/Files/{fileId}/Parts dit les morceaux déjà reçus : reprenez aux suivants.
4Les destinataires, puis l'envoi
PUT https://staging-api.docage.com/Transfers/{id}/Recipients
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
[ { "Email": "hugo.lefevre@example.com", "DisplayName": "Hugo Lefèvre" } ]curl -X PUT "https://staging-api.docage.com/Transfers/{id}/Recipients" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '[{"Email": "hugo.lefevre@example.com", "DisplayName": "Hugo Lefèvre"}]'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Put, "https://staging-api.docage.com/Transfers/{id}/Recipients");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
[
{
"Email": "hugo.lefevre@example.com",
"DisplayName": "Hugo Lefèvre"
}
]
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers/{id}/Recipients", {
method: "PUT",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify([{"Email": "hugo.lefevre@example.com", "DisplayName": "Hugo Lefèvre"}])
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;La liste envoyée remplace la précédente ; un contact se désigne aussi par ContactId.
POST https://staging-api.docage.com/Transfers/{id}/Send
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{ "TimeZoneId": "Europe/Paris" }curl -X POST "https://staging-api.docage.com/Transfers/{id}/Send" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{"TimeZoneId": "Europe/Paris"}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Transfers/{id}/Send");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"TimeZoneId": "Europe/Paris"
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Transfers/{id}/Send", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({"TimeZoneId": "Europe/Paris"})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Chaque destinataire reçoit son lien par email ; en lien commun, la réponse porte le lien à partager (SharedLinkUrl).
5Suivre, prolonger, révoquer
GET https://staging-api.docage.com/Transfers/{id}/Overview: par destinataire et par fichier, les téléchargements et leurs dates.POST https://staging-api.docage.com/Transfers/{id}/Extendprolonge la durée de vie ;POST https://staging-api.docage.com/Transfers/{id}/Resendrenvoie les liens.POST https://staging-api.docage.com/Transfers/{id}/Revokecoupe les liens et efface les fichiers aussitôt.
Les pièges
- Donnez exactement un
ETagpar morceau, tel que le stockage l'a rendu, guillemets compris. - Les fichiers exécutables, les scripts, les pages web et les fichiers vides sont refusés.
- Un échec d'email à un destinataire ne fait pas échouer l'envoi : vérifiez
NotifiedAtUtcde chaque destinataire dans l'aperçu. - Pour des fichiers déjà dans Docage (les documents d'un parcours, d'un contact…),
POST https://staging-api.docage.com/Files/Transferles copie et les envoie en une seule requête.