Ouvrir le portail d'un contact ou d'une société
Ouvrir l'espace où un client retrouve ses documents, en inviter les membres, y publier un parcours ou un document, et en fermer l'accès.
Un portail est l'espace où un client retrouve ce que vous mettez à sa disposition : les documents publiés — dont ceux des parcours terminés —, ses actions de parcours en attente, ses cartes. Il s'adresse à un contact, à une société (tous ses contacts) ou à un groupe : chaque contact de cette audience en est un membre, qui entre par son lien personnel.
1Lire le portail existant
GET https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…curl "https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…"using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Get, "https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
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/Portals/For/Company/00000000-0000-4000-8000-000000000101", {
headers: {
Authorization: `Bearer ${token}`
}
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;L'audience se désigne dans l'adresse : Contact, Company ou Group, puis l'identifiant de la fiche. La réponse est le portail
ouvert pour cette fiche, le plus récent s'il y en a plusieurs : son Id, son nom, s'il est ouvert (IsEnabled), son mode d'accès
(AccessMode), la date de sa dernière publication (LastPublicationAtUtc) et ses réglages (Settings). 404 : aucun portail —
la même réponse pour une fiche inconnue ou que vous ne voyez pas. Un contact est aussi membre du portail de sa société : cherchez par
sa société quand il n'en a pas à lui.
2Ouvrir un portail
POST https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Name": "Espace Atelier Lumière",
"AccessMode": 3,
"IncludePast": true,
"WelcomeText": "Retrouvez ici les documents de votre dossier."
}curl -X POST "https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Name": "Espace Atelier Lumière",
"AccessMode": 3,
"IncludePast": true,
"WelcomeText": "Retrouvez ici les documents de votre dossier."
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Portals/For/Company/00000000-0000-4000-8000-000000000101");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Name": "Espace Atelier Lumière",
"AccessMode": 3,
"IncludePast": true,
"WelcomeText": "Retrouvez ici les documents de votre dossier."
}
""", 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/Portals/For/Company/00000000-0000-4000-8000-000000000101", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Name": "Espace Atelier Lumière",
"AccessMode": 3,
"IncludePast": true,
"WelcomeText": "Retrouvez ici les documents de votre dossier."
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Tout est facultatif. La réponse est le portail ouvert, et ses membres sont posés : un par contact de l'audience, sans lien ni avis — l'invitation est le geste suivant.
TemplateId: le modèle de portail ; omis, le modèle « Espace client » de la plateforme. Les modèles de l'organisation se lisent parQUERY https://staging-api.docage.com/Portals/TemplatesIdAndName(avec"IncludeSystem": true, ceux de la plateforme aussi). Le portail reçoit une copie des réglages du modèle : modifier le modèle ensuite ne le change pas.AccessMode:1le lien seul,2le lien et un mot de passe commun,3le lien et un code à usage unique envoyé par email ou par SMS. Omis, celui que propose le modèle.Password: le mot de passe commun du mode2, 6 caractères au moins. Il est exigé dès que le mode2est demandé, ou proposé par le modèle ; ignoré pour un autre mode. Il n'est jamais rendu.IncludePast: publier aussitôt les parcours déjà terminés de l'audience. Omis, ce que règle le modèle.
Les refus :
404: la fiche est introuvable, ou vous ne la voyez pas — la même réponse.422: une fiche d'une autre organisation, un mode d'accès inconnu, ou le mode2sans mot de passe ou avec un mot de passe trop court ; la raison est dans la réponse.400: aucun modèle n'est disponible.
Attention
POST ouvre toujours un nouveau portail, même s'il en existe un pour la même fiche. Lisez d'abord le portail existant (§ 1).
Le mode et le mot de passe se changent ensuite par PUT https://staging-api.docage.com/Portals/{id}/AccessMode, avec { "Mode": 2, "Password": "…" } :
6 caractères au moins, ou celui déjà posé si Password est omis ; sinon 422. Un portail en mode 2 n'existe jamais sans mot de
passe — aucun membre n'y entrerait.
3Inviter les membres
POST https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Members/Invite
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{ "Channel": 1 }curl -X POST "https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Members/Invite" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{"Channel": 1}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Members/Invite");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Channel": 1
}
""", 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/Portals/00000000-0000-4000-8000-000000000951/Members/Invite", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({"Channel": 1})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Sans MemberIds, tous les membres qui n'ont pas encore d'accès valide sont invités, membres révoqués exceptés ; un membre sans
adresse email (Channel 1) ou sans mobile (Channel 2, par SMS) est passé. Chacun reçoit son lien personnel, valable le temps
que règle le portail, et un avis. Avec MemberIds, seuls ceux-là — un membre révoqué désigné retrouve l'accès, par un lien neuf —, et
un membre désigné qui n'a pas l'adresse du canal fait refuser l'envoi.
La réponse est la liste des membres, à jour : Id, ContactId, ContactName, Email, InvitedAtUtc, LinkExpirationDate,
IsRevoked, et PortalUrl, l'adresse personnelle du membre — un secret, à ne pas journaliser. La même liste se relit par
GET https://staging-api.docage.com/Portals/{id}/Members. Un membre dont vous ne voyez pas le contact y reste sans nom, sans adresse email et sans adresse
personnelle (IsContactHidden vaut true), en fin de liste : seul l'état de son accès se lit.
400 : portail fermé, membre désigné qui n'appartient pas au portail ou sans l'adresse du canal, aucun membre à inviter, avis qui n'a
pas pu partir. Les avis partent un à un : après un refus, relisez les membres avant de recommencer, de premiers avis ont pu partir.
Un contact arrivé depuis dans l'audience — un nouveau contact de la société — n'est pas encore membre :
POST https://staging-api.docage.com/Portals/{id}/Members/Sync l'ajoute, sans lien ni avis — la réponse est la liste des identifiants des membres ajoutés —,
puis invitez-le.
4Publier un parcours ou un document
POST https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Publications
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Kind": 2,
"EntityTypeName": "Transaction",
"EntityId": "00000000-0000-4000-8000-000000000981",
"Title": "Contrat de prestation signé",
"Category": "Contrats",
"IsPinned": true
}curl -X POST "https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Publications" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Kind": 2,
"EntityTypeName": "Transaction",
"EntityId": "00000000-0000-4000-8000-000000000981",
"Title": "Contrat de prestation signé",
"Category": "Contrats",
"IsPinned": true
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Portals/00000000-0000-4000-8000-000000000951/Publications");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Kind": 2,
"EntityTypeName": "Transaction",
"EntityId": "00000000-0000-4000-8000-000000000981",
"Title": "Contrat de prestation signé",
"Category": "Contrats",
"IsPinned": 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/Portals/00000000-0000-4000-8000-000000000951/Publications", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Kind": 2,
"EntityTypeName": "Transaction",
"EntityId": "00000000-0000-4000-8000-000000000981",
"Title": "Contrat de prestation signé",
"Category": "Contrats",
"IsPinned": true
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;KindetEntityTypeNamevont ensemble :1un fichier (TransactionFile,ContactFile…),2un parcours (Transaction),3un classeur (Box),4une carte (PipelineItem). La source doit être une fiche que vous voyez.- La réponse est l'identifiant de la publication. Publier de nouveau la même source met à jour sa publication au lieu d'en créer une seconde.
400: type inconnu ou qui ne concorde pas avecKind, source introuvable ou que vous ne voyez pas, parcours d'essai.
Les portails où une fiche peut paraître — ceux dont l'audience la touche — se lisent par
GET https://staging-api.docage.com/Portals/Candidates/Transaction/{id}, chacun avec AlreadyPublished ; 404 pour une fiche inconnue ou que vous ne voyez
pas. Un portail dont les réglages publient seuls les
parcours terminés (Settings.AutoPublishCompletedTransactions, tenu de son modèle) reçoit de lui-même tout parcours terminé dont un
membre est participant ou observateur.
Les publications d'un portail : GET https://staging-api.docage.com/Portals/{id}/Publications. Retirer une publication :
DELETE https://staging-api.docage.com/Portals/{id}/Publications/{publicationId} — elle cesse d'être visible, son historique reste.
5Voir le portail comme un membre
GET https://staging-api.docage.com/Portals/{id}/Content/{memberId} rend ce que la page du membre affiche — publications et fichiers, actions à faire,
cartes —, sans compter de visite. Les actions à faire y sont sans leur lien (Url vide) : il ouvrirait l'action au nom du contact.
Un membre révoqué, un portail fermé, ou un membre dont vous ne voyez pas le contact, répond 404.
6Révoquer un membre, fermer le portail
PUT https://staging-api.docage.com/Portals/{id}/Members/{memberId}/Revoke: le lien du membre cesse aussitôt d'ouvrir le portail. Une nouvelle invitation qui le désigne lui rend l'accès, par un lien neuf.PUT https://staging-api.docage.com/Portals/{id}/Enabled/false: le portail ne montre plus rien à aucun membre ; les liens restent en place, etPUT https://staging-api.docage.com/Portals/{id}/Enabled/truele rouvre — sauf un portail en mode2qui n'aurait pas de mot de passe (422) : posez-le d'abord.
Ces gestes exigent de pouvoir modifier le portail : sinon, comme pour un portail introuvable, 404.
Les pièges
- Un portail s'ouvre et se lit dans l'organisation de l'utilisateur authentifié, pour une fiche de cette organisation qu'il voit : pour une organisation cliente, faites l'appel avec un utilisateur de cette organisation — voir Organisations et intégrateurs.
- Une organisation qui n'est pas encore en production crée des parcours d'essai : ils ne se publient pas dans un portail.
- Inviter un membre ouvre la porte à tout ce que le portail publie : publiez avant d'inviter, ou vérifiez le contenu par le § 5.
- Le portail d'une société sert tous ses contacts : un document qui ne concerne qu'une personne se publie dans son portail.