NAV

Référence API

L’API de Coanda est organisée autour de REST. Notre API est predictible, a des URLs orientée ressource, accepte des corps de requêtes encodés en JSON, retourne des réponses encodées en JSON et utilise le standard HTTP pour les codes de retour et les méthodes.

Vous pouvez voir des exemples de code dans la zone sombre à droite.

Veuillez lire la partie sur l’authentification en premier SVP.

Authentification

Pour autoriser une requête, procédez comme suit:

# En shell, vous pouvez passer le bon header avec chaque requête
curl "api_endpoint_here"
  -H "Authorization: Bearer myToken"

Remplacez myToken avec le token généré.

Coanda utilise des tokens JWT pour autoriser l’accès à son API.

Coanda s’attend à ce que le token JWT soit inclus dans toutes les requêtes API dans un header qui à la structure suivante:

Authorization: Bearer myToken

Générer un token d’autorisation (déprécié)

curl "https://aaaic-backend.ppd.rafa.3a-digital.fr/user-service/v1/token/acquire?username=myuser%40test.com&password=testpassword"
-H "accept: text/plain"

La commande ci-dessus retourne un token JWT en string brut dans le corps de la réponse:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao

Ce endpoint génère un token JWT à partir d’une combinaison de nom d’utilisateur et mot de passe.

Requête HTTP

GET /user-service/v1/token/acquire

Paramètres d’URL

ParamètreDescription
usernameVotre username/clientId. Doit être envoyé url_encoded.
passwordVotre password/clientSecret. Doit être envoyé url_encoded.

Générer un token d’autorisation (OAuth)

curl --request POST \
  --url "https://aaaic-backend.ppd.rafa.3a-digital.fr/user-service/v1/token/oauth" \
  --header "content-type: application/x-www-form-urlencoded" \
  --data grant_type=client_credentials \
  --data client_id=YOUR_CLIENT_ID \
  --data client_secret=YOUR_CLIENT_SECRET

La commande ci-dessus retourne une réponse JSON:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao",
  "token_type": "Bearer"
}

Ce endpoint génère un token JWT en utilisant le flux OAuth 2.0 Client Credentials.

Requête HTTP

POST /user-service/v1/token/oauth

Corps de la requête (application/x-www-form-urlencoded)

ParamètreDescription
grant_typeDoit être défini à client_credentials.
client_idVotre identifiant client.
client_secretVotre secret client.

Réponse

ChampDescription
access_tokenLe token JWT généré.
token_typeLe type de token. Toujours Bearer.

Module Simulateur

Le module simulateur expose plusieurs endpoints permettant de réaliser différents calculs sur un projet d’épargne. Les trois endpoints principaux sont chacun dédié à un type de gestion (libre, déléguée, à horizon)

Gestion Libre

curl \
  --location 'https://aaaic-backend.ppd.rafa.3a-digital.fr/simulator-service/simulator/free_management' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <myToken>' \
  --data '{
    "simulation_start_date": "202008",
    "simple_deposits": [
      {
        "amount": 5000,
        "date": "202010"
      }
    ],
    "periodic_deposits": [
      {
        "amount": 197.2,
        "start_date": "202008",
        "end_date": "202507",
        "frequency": "MONTHLY"
      }
    ],
    "portfolio_composition": [
      {
        "isin": "LU1883308352",
        "currency": "GBP",
        "percentage": 50,
      },
      {
        "isin": "LU1681046931",
        "currency": "EUR",
        "percentage": 50,
      },
    ],
    "target_amount": 5000,
    "horizon": 60,
    "current_savings": 1000,
    "simulator_uuid": "aaaic:simulators:243",
}'

La commande ci-dessus retourne un objet JSON structuré de cette façon:

{
  "success_percentage": "float",
  "graphs": {
    "nb_scenarios": "int",
    "scenarios_smooth": [
      {
        "name": "string",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ]
      }
    ],
    "synthesis": {
      "savings": {
        "x": "float",
        "y": "float"
      },
      "median": {
        "x": "float",
        "y": "float"
      },
      "lower_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "mid_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "upper_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      }
    },
    "success_percentage": "float",
    "scenarios_perc_above_cumulative_savings": "float",
    "id": "string",
    "scenarios": [
      {
        "name": "savings",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ],
        "lineWidth": "float",
        "zIndex": "float"
      }
    ]
  },
  "statistics": {
    "mar_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "sharp_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_return": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "max_drawdown": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_volatility": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    }
  },
  "scenarios_table": {
    "capital_distribution_at_horizon": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "capital_gain_or_loss": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "absolute_return": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "cumulative_savings": "float",
    "gross_cumulative_savings": "float"
  },
  "uc_allocation": [
    {
      "series": "string",
      "percentage": "float"
    }
  ]
}

Ce endpoint réalise une simulation pour un projet d’épargne en gestion libre.

Requête HTTP

POST /simulator-service/simulator/free_management

Corps de la requête

Le corps de la requête est un objet JSON représentant une demande de simulation.

L’objet SimulationRequest

ParamètreObligatoireTypeDescription
simulator_uuidtruestringIdentifiant unique du simulateur. Fourni par AAA.
target_amountfalsenumberLa somme d’argent que l’on souhaite atteindre.
horizontrueintegerLa longueur du projet d’epargne (en mois).
current_savingsfalsenumberLe montant actuel de l’épargne.
start_datetruestringDate de début de la simulation. Le format est YYYYMM.
simple_depositsfalse[SimpleCashFlow]La liste des versements ponctuels anticipés.
periodic_depositsfalse[PeriodicCashFlow]La liste des versements récurrents anticipés.
simple_withdrawalsfalse[SimpleCashFlow]La liste des rachats ponctuels anticipés.
periodic_withdrawalsfalse[PeriodicCashFlow]La liste des rachats récurrents anticipés.
portfolio_compositiontrue[WeightedAsset]La composition du portefeuille.

The WeightedAsset object

ParameterMandatoryTypeDescription
isintruestringLe code ISIN du support.
currencytruestringLa devise du support, identifié par un trigrame (ex: “EUR”).
percentagetruenumberLe pourcentage investi dans cet support.

L’objet SimpleCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
datetruestringLa date du mouvement. Le format est YYYYMM.

L’objet PeriodicCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
start_datetruestringLa date de début du mouvement récurrent. Le format est YYYYMM.
end_datetruestringLa date de fin du mouvement récurrent. Le format est YYYYMM.
frequencytruestringLa fréquence de la récurrence. Les valeurs possibles sont: MONTHLY/QUARTERLY/YEARLY/SEMI_ANNUALLY

Gestion Pilotée

curl \
  --location 'https://aaaic-backend.ppd.rafa.3a-digital.fr/simulator-service/simulator/delegated_management' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <myToken>' \
  --data '{
    "simulation_start_date": "202008",
    "simple_deposits": [
      {
        "amount": 5000,
        "date": "202010"
      }
    ],
    "periodic_deposits": [
      {
        "amount": 197.2,
        "start_date": "202008",
        "end_date": "202507",
        "frequency": "MONTHLY"
      }
    ],
    "target_amount": 5000,
    "horizon": 60,
    "current_savings": 1000,
    "simulator_uuid": "aaaic:simulators:236",
    "profile_idx": 2
}'

La commande ci-dessus retourne un objet JSON structuré de cette façon:

{
  "success_percentage": "float",
  "graphs": {
    "nb_scenarios": "int",
    "scenarios_smooth": [
      {
        "name": "string",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ]
      }
    ],
    "synthesis": {
      "savings": {
        "x": "float",
        "y": "float"
      },
      "median": {
        "x": "float",
        "y": "float"
      },
      "lower_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "mid_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "upper_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      }
    },
    "success_percentage": "float",
    "scenarios_perc_above_cumulative_savings": "float",
    "id": "string",
    "scenarios": [
      {
        "name": "savings",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ],
        "lineWidth": "float",
        "zIndex": "float"
      }
    ]
  },
  "statistics": {
    "mar_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "sharp_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_return": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "max_drawdown": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_volatility": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    }
  },
  "scenarios_table": {
    "capital_distribution_at_horizon": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "capital_gain_or_loss": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "absolute_return": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "cumulative_savings": "float",
    "gross_cumulative_savings": "float"
  },
  "uc_allocation": [
    {
      "series": "string",
      "percentage": "float"
    }
  ]
}

Ce endpoint réalise une simulation pour un projet d’épargne en gestion pilotée.

Requête HTTP

POST /simulator-service/simulator/delegated_management

Corps de la requête

Le corps de la requête est un objet JSON représentant une demande de simulation.

L’objet SimulationRequest

ParamètreObligatoireTypeDescription
simulator_uuidtruestringIdentifiant unique du simulateur. Fourni par AAA.
target_amountfalsenumberLa somme d’argent que l’on souhaite atteindre.
horizontrueintegerLa longueur du projet d’epargne (en mois).
current_savingsfalsenumberLe montant actuel de l’épargne.
start_datetruestringDate de début de la simulation. Le format est YYYYMM.
simple_depositsfalse[SimpleCashFlow]La liste des versements ponctuels anticipés.
periodic_depositsfalse[PeriodicCashFlow]La liste des versements récurrents anticipés.
simple_withdrawalsfalse[SimpleCashFlow]La liste des rachats ponctuels anticipés.
periodic_withdrawalsfalse[PeriodicCashFlow]La liste des rachats récurrents anticipés.
profile_idxtrueintegerIdentifiant unique du profil de gestion pilotée. Fourni par AAA.

L’objet SimpleCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
datetruestringLa date du mouvement. Le format est YYYYMM.

L’objet PeriodicCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
start_datetruestringLa date de début du mouvement récurrent. Le format est YYYYMM.
end_datetruestringLa date de fin du mouvement récurrent. Le format est YYYYMM.
frequencytruestringLa fréquence de la récurrence. Les valeurs possibles sont: MONTHLY/QUARTERLY/YEARLY/SEMI_ANNUALLY

Gestion Pilotée à Horizon

curl \
  --location 'https://aaaic-backend.ppd.rafa.3a-digital.fr/simulator-service/simulator/glidepath_management' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <myToken>' \
  --data '{
    "simulation_start_date": "202008",
    "simple_deposits": [
      {
        "amount": 5000,
        "date": "202010"
      }
    ],
    "periodic_deposits": [
      {
        "amount": 197.2,
        "start_date": "202008",
        "end_date": "202507",
        "frequency": "MONTHLY"
      }
    ],
    "target_amount": 5000,
    "horizon": 60,
    "current_savings": 1000,
    "simulator_uuid": "aaaic:simulators:170",
    "profile_idx": 2,
    "age": 35
}'

La commande ci-dessus retourne un objet JSON structuré de cette façon:

{
  "success_percentage": "float",
  "graphs": {
    "nb_scenarios": "int",
    "scenarios_smooth": [
      {
        "name": "string",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ]
      }
    ],
    "synthesis": {
      "savings": {
        "x": "float",
        "y": "float"
      },
      "median": {
        "x": "float",
        "y": "float"
      },
      "lower_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "mid_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      },
      "upper_area": {
        "x": "float",
        "high": "float",
        "low": "float"
      }
    },
    "success_percentage": "float",
    "scenarios_perc_above_cumulative_savings": "float",
    "id": "string",
    "scenarios": [
      {
        "name": "savings",
        "data": [
          {
            "x": "float",
            "y": "float"
          }
        ],
        "lineWidth": "float",
        "zIndex": "float"
      }
    ]
  },
  "statistics": {
    "mar_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "sharp_ratio": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_return": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "max_drawdown": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    },
    "annualized_volatility": {
      "quantile_25": "float",
      "quantile_2.5": "float",
      "quantile_50": "float",
      "quantile_75": "float",
      "quantile_97.5": "float"
    }
  },
  "scenarios_table": {
    "capital_distribution_at_horizon": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "capital_gain_or_loss": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "absolute_return": {
      "max": "float",
      "min": "float",
      "in_between": {
        "high": "float",
        "low": "float"
      }
    },
    "cumulative_savings": "float",
    "gross_cumulative_savings": "float"
  },
  "uc_allocation": [
    {
      "series": "string",
      "percentage": "float"
    }
  ]
}

Ce endpoint réalise une simulation pour un projet d’épargne en gestion pilotée.

Requête HTTP

POST /simulator-service/simulator/glidepath_management

Corps de la requête

Le corps de la requête est un objet JSON représentant une demande de simulation.

L’objet SimulationRequest

ParamètreObligatoireTypeDescription
simulator_uuidtruestringIdentifiant unique du simulateur. Fourni par AAA.
target_amountfalsenumberLa somme d’argent que l’on souhaite atteindre.
horizontrueintegerLa longueur du projet d’epargne (en mois).
current_savingsfalsenumberLe montant actuel de l’épargne.
start_datetruestringDate de début de la simulation. Le format est YYYYMM.
simple_depositsfalse[SimpleCashFlow]La liste des versements ponctuels anticipés.
periodic_depositsfalse[PeriodicCashFlow]La liste des versements récurrents anticipés.
simple_withdrawalsfalse[SimpleCashFlow]La liste des rachats ponctuels anticipés.
periodic_withdrawalsfalse[PeriodicCashFlow]La liste des rachats récurrents anticipés.
profile_idxtrueintegerIdentifiant unique du profil de gestion pilotée. Fourni par AAA.
agetrueintegerL’age du souscripteur.

L’objet SimpleCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
datetruestringLa date du mouvement. Le format est YYYYMM.

L’objet PeriodicCashFlow

ParamètreObligatoireTypeDescription
amounttruenumberLa somme déposée ou retirée.
start_datetruestringLa date de début du mouvement récurrent. Le format est YYYYMM.
end_datetruestringLa date de fin du mouvement récurrent. Le format est YYYYMM.
frequencytruestringLa fréquence de la récurrence. Les valeurs possibles sont: MONTHLY/QUARTERLY/YEARLY/SEMI_ANNUALLY

Module Premia

Le module Premia est un outil intelligent qui accompagne les conseillers à chaque étape du devoir de conseil. Définition du profil de risque et des objectifs de l’épargnant, intégration de ses préférences ESG, pour une préconisation d’allocations sur-mesure grâce à un moteur algorithmique d’adéquation. Le tout permettant de générer automatiquement une proposition d’investissement complète, conforme et prête à partager avec l’épargnant.

Ce endpoint permet de créer une session Premia. Vous vous authentifiez avec un JWT, créez une session via l’API, puis redirigez l’utilisateur vers Premia avec le hash de session retourné.

Créer une session Premia

# Example 1 : souscription à un nouveau contrat

curl \
  --location '{BASE_BACKEND_URL}/premia/api/v1/sessions' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <myToken>' \
  --data '{
    "recoJourneyUuid": "aaaic:reco_journeys:4",
    "extProductCode": "PERZEN",
    "extSessionCode": "123456",
    "contactEmail": "adeline.monet@gmail.com",
    "clientLastName": "Monet",
    "clientFirstName": "Adeline",
    "clientBirthDate": "19800101",
    "coSubscriberLastName": "Jean",
    "coSubscriberFirstName": "Monet",
    "coSubscriberBirthDate": "19780331",
    "legalPersonName": "",
    "legalPersonIdentifier": "",
    "legalPersonRepresentativeLastName": "",
    "legalPersonRepresentativeFirstName": "",
    "depositInitialEnabled": true,
    "depositInitial": 5000
  }'
  
  # Example 2 : versement / rachat / arbitrage
  
  curl \
  --location '{BASE_BACKEND_URL}/premia/api/v1/sessions' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <myToken>' \
  --data '{
    "recoJourneyUuid": "aaaic:reco_journeys:13",
    "extSessionCode": "123456",
    "extProductCode": "01t0N00000B9B8pQAF",
    "contactEmail": "adeline.monet@gmail.com",
    "clientLastName": "Monet",
    "clientFirstName": "Adeline",
    "clientBirthDate": "19800101",
    "coSubscriberLastName": "Jean",
    "coSubscriberFirstName": "Monet",
    "coSubscriberBirthDate": "19780331",
    "legalPersonName": "",
    "legalPersonIdentifier": "",
    "legalPersonRepresentativeLastName": "",
    "legalPersonRepresentativeFirstName": "",
    "depositInitialEnabled": false,
    "clientRiskKey": "2",
    "clientRiskKeyLastUpdateDate": "20250101",
    "hasSustainablePreferences": true,
    "minSustainableInvestments": 15,
    "minTaxonomyAlignment": null,
    "minCoveragePai": 0.50,
    "greenhouseGasEmissions": true,
    "impactOnBiodiversity": false,
    "waterEmissions": true,
    "hazardousWaste": false,
    "controversialWeapons": false,
    "monitoringOfInternationalPrinciples": false,
    "respectOfInternationalPrinciples": false,
    "genderPayGap": false,
    "lowBoardGenderDiversity": false,
    "clientEsgLastUpdateDate": "20250101",
    "periodicDepositsEnabled": true,
    "regularContributionsAmount": 500,
    "regularContributionsFormat": "CHOSEN_FREQUENCY",
    "regularContributionsFrequency": "MONTHLY",
    "currentComposition": {
        "compositionParts": [
            {
                "partWeights": [
                    {
                        "amount": 400,
                        "displayName": "Mirova Europe Environnement",
                        "extCode": "LU0914733059"
                    },
                    {
                        "amount": 300,
                        "displayName": "Afer Rendement Juin 2023",
                        "extCode": "FR5272AB0288"
                    },
                    {
                        "amount": 250,
                        "displayName": "SC Advenis Immo Capital",
                        "extCode": "P801_SCI001"
                    }
                ],
                "type": "FREE_MANAGEMENT"
            }
        ]
    }
  }'

La commande ci-dessus retourne un objet JSON structuré de cette façon :

{
  "sessionHash": "abc123"
}

Requête HTTP

POST /premia/api/v1/sessions

Corps de la requête

Le corps de la requête est un objet JSON contenant toutes les informations nécessaires pour initier une session sur Premia. Selon le cas d’usage, il est construit différemment. Des exemples sont fournis à droite pour illustrer les cas suivants :

Réponse

En réponse, le service fournit un hash de session, nécessaire pour initier la session correspondante sur Premia.

L'objet PremiaSessionRequest

ParamètreObligatoireTypeDescription
recoJourneyUuidtruestringIdentifiant de la configuration Premia à utiliser. Fourni par AAA.
extProductCodetruestringVotre code produit dans le système partenaire (ex : PERZEN).
extSessionCodetruestringVotre référence interne pour la traçabilité.
contactEmailfalsestringEmail de contact pour les notifications.
clientLastNametruestringNom de famille du client.
clientFirstNametruestringPrénom du client.
clientBirthDatetruestringDate de naissance du client au format YYYYMMDD.
coSubscriberLastNamefalsestringNom de famille du co-souscripteur (si applicable).
coSubscriberFirstNamefalsestringPrénom du co-souscripteur (si applicable).
coSubscriberBirthDatefalsestringDate de naissance du co-souscripteur au format YYYYMMDD (si applicable).
legalPersonNamefalsestringNom de la personne morale (pour les souscriptions d’entreprise).
legalPersonIdentifierfalsestringIdentifiant de la personne morale (ex : SIREN).
legalPersonRepresentativeLastNamefalsestringNom du représentant légal (pour les souscriptions d’entreprise).
legalPersonRepresentativeFirstNamefalsestringPrénom du représentant légal (pour les souscriptions d’entreprise).
depositInitialEnabledfalsebooleanIndique si un dépôt initial est activé.
depositInitialconditionnelnumberMontant du dépôt initial. Obligatoire quand depositInitialEnabled est true.
clientRiskKeyfalsestringProfil de risque du client. Clé de risque (ex : “2”).
clientRiskKeyLastUpdateDatefalsestringDate de dernière mise à jour du profil de risque au format YYYYMMDD.
hasSustainablePreferencesfalsebooleanLe client a des préférences ESG ?
minSustainableInvestmentsfalsenumber% minimum d’investissements durables (format “15” pour 15%).
minTaxonomyAlignmentfalsenumber% minimum aligné taxonomie (format “15” pour 15%).
minCoveragePaifalsenumber% minimum de couverture PAI (format “15” pour 15%).
greenhouseGasEmissionsfalsebooleanPAI Climat.
impactOnBiodiversityfalsebooleanPAI Biodiversité.
waterEmissionsfalsebooleanPAI Qualité de l’eau.
hazardousWastefalsebooleanPAI Gestion responsable des déchets.
controversialWeaponsfalsebooleanPAI Contrôle des armes controversées.
monitoringOfInternationalPrinciplesfalsebooleanPAI Contrôle des normes internationales.
respectOfInternationalPrinciplesfalsebooleanPAI Respect des normes internationales.
genderPayGapfalsebooleanPAI Égalité de rémunération hommes/femmes.
lowBoardGenderDiversityfalsebooleanPAI Mixité des conseils d’administration.
clientEsgLastUpdateDatefalsestringDate de dernière mise à jour des préférences ESG au format YYYYMMDD.
periodicDepositsEnabledfalsebooleanVersements programmés en place ?
regularContributionsAmountconditionnelnumberMontant du versement programmé. Obligatoire si periodicDepositsEnabled est true.
regularContributionsFormatfalsestringFormat des contributions. Valeurs : “CHOSEN_FREQUENCY”.
regularContributionsFrequencyfalsestringFréquence des contributions. Valeurs : “MONTHLY”, “QUARTERLY”, “SEMIANNUALLY”, “ANNUALLY”.
currentCompositionfalseobjectComposition de l’allocation actuelle.
extCodefalsestringCode du support. Contexte : dans currentComposition.compositionParts[].partWeights[].
displayNamefalsestringNom de l’actif financier. Contexte : dans currentComposition.compositionParts[].partWeights[].
amountfalsenumberValeur marchande de la ligne. Contexte : dans currentComposition.compositionParts[].partWeights[].

Si l’entrée n’est pas valide ou que vous n’avez pas accès, l’API retournera des erreurs HTTP standard (400, 403, 404) avec un corps JSON décrivant le problème.

Rediriger l'utilisateur vers Premia

Une fois que vous recevez le sessionHash, redirigez le navigateur de l’utilisateur vers Premia en utilisant l’URL suivante :

{BASE_UI_URL}/premia/sessions?hash={sessionHash}

Remplacez {BASE_UI_URL} par l’hôte Premia avec lequel vous vous intégrez (staging, production, etc.).

const res = await fetch(`${BASE_BACKEND_URL}/premia/api/v1/sessions`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`,
  },
  body: JSON.stringify(payload),
});
const { sessionHash } = await res.json();
window.location.href = `${BASE_UI_URL}/premia/sessions?hash=${sessionHash}`;

Reprendre une session Premia

Une fois que vous connaissez le sessionHash, redirigez le navigateur de l’utilisateur vers Premia en utilisant l’URL suivante :

{BASE_UI_URL}/premia/sessions?hash={sessionHash}

Remplacez {BASE_UI_URL} par l’hôte Premia avec lequel vous vous intégrez (staging, production, etc.).

Module PMS

Le module PMS permet à une société de gestion de lire ses propres données dans le PMS Coanda : les supports d’un bassin d’investissement, les performances et caractéristiques d’un profil, et ses données réglementaires PRIIPs (EPT).

Les trois endpoints sont en lecture seule. Ils sont ouverts à toute société de gestion authentifiée, chacune limitée à son périmètre : les profils dont elle est propriétaire, et les bassins de son propre PMS - ceux qu’elle a créés comme ceux qu’un assureur lui a affectés.

Les dates sont échangées au format ISO, AAAA-MM-JJ, en entrée comme en sortie.

Récupérer les supports d’un bassin d’investissement

curl \
  --location '{BASE_BACKEND_URL}/pms/api/v1/investment_pools/aaaic:investment_pools:6/supports' \
  --header 'Authorization: Bearer <myToken>'

La commande ci-dessus renvoie un JSON structuré comme suit :

{
  "investmentPoolUuid": "aaaic:investment_pools:6",
  "investmentPoolName": "Bassin Actions Monde",
  "supportCount": 2,
  "supports": [
    {
      "seriesUuid": "aaaic:series:13611",
      "isin": "LU1234567890",
      "name": "ESG Equity Europe",
      "assetClassLevel1": "EQUITIES",
      "assetClassLevel2": "LARGE_CAP_EQUITIES",
      "geoZoneLevel1": "EUROPE",
      "geoZoneLevel2": "EUROZONE",
      "hedged": false,
      "inHouse": true,
      "inHouseMatchedKeyword": "AM INVEST"
    },
    {
      "seriesUuid": "aaaic:series:9042",
      "isin": "IE00B4L5Y983",
      "name": "iShares Core MSCI World",
      "assetClassLevel1": "EQUITIES",
      "assetClassLevel2": null,
      "geoZoneLevel1": "GLOBAL",
      "geoZoneLevel2": null,
      "hedged": true,
      "inHouse": false,
      "inHouseMatchedKeyword": null
    }
  ]
}

Cet endpoint renvoie la buy list d’un bassin d’investissement : tous ses supports, avec leurs caractéristiques.

Requête HTTP

GET /pms/api/v1/investment_pools/{uuid}/supports

Paramètres de chemin

ParamètreObligatoireTypeDescription
uuidouistringIdentifiant du bassin, par exemple aaaic:investment_pools:6.

Réponse

La réponse n’est pas paginée : un bassin compte au plus quelques centaines de supports. supportCount vous permet un contrôle de cohérence de votre côté. Les supports sont triés par ISIN.

L’objet Support

ParamètreTypeDescription
seriesUuidstringIdentifiant du support.
isinstringISIN du support. Peut être null pour un support sans ISIN.
namestringNom du support, tel qu’affiché dans votre PMS.
assetClassLevel1stringClasse d’actif, niveau 1. Null si le support n’est pas encore qualifié.
assetClassLevel2stringClasse d’actif, niveau 2. Null si le support n’est pas encore qualifié.
geoZoneLevel1stringZone géographique, niveau 1. Null si le support n’est pas encore qualifié.
geoZoneLevel2stringZone géographique, niveau 2. Null si le support n’est pas encore qualifié.
hedgedbooleanIndique si le support est couvert en devise. Null si le drapeau n’est pas renseigné.
inHousebooleanIndique s’il s’agit d’un de vos propres fonds.
inHouseMatchedKeywordstringLe mot-clé configuré qui a correspondu, pour auditer les faux positifs. Null si aucun.

Si le bassin n’existe pas, vous recevez un 404 PMS_INVESTMENT_POOL_NOT_FOUND. S’il appartient à une autre société de gestion, un 403 PMS_INVESTMENT_POOL_NOT_OWNED.

Récupérer les performances et informations d’un profil

# Sur une periode donnee
curl \
  --location '{BASE_BACKEND_URL}/pms/api/v1/profiles/performances?profile_uuid=aaaic:aaa_model_portfolios:527&start_date=2024-01-01&end_date=2026-06-30' \
  --header 'Authorization: Bearer <myToken>'

# Depuis l'inception, jusqu'a la date du jour
curl \
  --location '{BASE_BACKEND_URL}/pms/api/v1/profiles/performances?profile_uuid=aaaic:aaa_model_portfolios:527' \
  --header 'Authorization: Bearer <myToken>'

La commande ci-dessus renvoie un JSON structuré comme suit :

{
  "insurerCode": "DYN-01",
  "profileName": "Profil Dynamique",
  "profileUuid": "aaaic:aaa_model_portfolios:527",
  "investmentPoolUuid": "aaaic:investment_pools:6",
  "inceptionDate": "2019-04-01",
  "startDate": "2024-01-01",
  "endDate": "2026-06-30",
  "performances": {
    "net":                   [ { "date": "2024-01-02", "value": 128.4312 } ],
    "gross":                 [ { "date": "2024-01-02", "value": 133.1120 } ],
    "netCompositionDates":   [ { "date": "2024-01-02", "value": 127.8801 } ],
    "grossCompositionDates": [ { "date": "2024-01-02", "value": 132.5410 } ],
    "netUnitLinked":         null,
    "grossUnitLinked":       null
  },
  "guaranteedFunds": [
    {
      "seriesUuid": "aaaic:series:4221",
      "isin": "FR0000000000",
      "name": "Fonds Euros",
      "values": [ { "date": "2024-01-02", "value": 112.4400 } ]
    }
  ],
  "volatility": 7.42,
  "feeConfigurations": [
    {
      "configurationDate": "2024-01-01",
      "annualFees": 0.80,
      "feesUnitLinkedAssets": 0.8000,
      "feesEtfAssets": 0.4000,
      "feesGuaranteedFunds": 0.0000,
      "feesEtfTransactions": 0.1000,
      "feesFrequency": "MONTHLY",
      "feesDeductionDay": 1,
      "feesDeductionMonth": null,
      "feesDeductionWeekDay": null,
      "subscriptionSeriesFees": [
        { "seriesUuid": "aaaic:series:13611", "isin": "LU1234567890", "seriesFee": 0.2500 }
      ]
    }
  ],
  "compositions": [
    {
      "compositionDate": "2024-03-11",
      "executionDate": "2024-03-14",
      "allocations": [
        { "seriesUuid": "aaaic:series:13611", "isin": "LU1234567890", "name": "ESG Equity Europe", "weight": 33.45 },
        { "seriesUuid": "aaaic:series:4221",  "isin": "FR0000000000", "name": "Fonds Euros",       "weight": 66.55 }
      ]
    }
  ],
  "driftedComposition": {
    "referenceDate": "2026-06-30",
    "lastExecutionDate": "2026-05-14",
    "allocations": [
      { "seriesUuid": "aaaic:series:13611", "isin": "LU1234567890", "name": "ESG Equity Europe", "weight": 33.45, "driftedWeight": 34.12 },
      { "seriesUuid": "aaaic:series:4221",  "isin": "FR0000000000", "name": "Fonds Euros",       "weight": 66.55, "driftedWeight": 65.88 }
    ]
  }
}

Cet endpoint renvoie tout ce qu’il faut savoir sur l’un de vos profils sur une période : courbes de performance, volatilité, fonds en euros, historique des frais, historique des réallocations et allocation réellement détenue en fin de période.

Requête HTTP

GET /pms/api/v1/profiles/performances

Paramètres de requête

ParamètreObligatoireTypeDescription
profile_uuidouistringIdentifiant unique du profil, tel que renvoyé dans le champ profileUuid.
start_datenonstringDébut de la période, inclus. Par défaut, la date d’inception du profil.
end_datenonstringFin de la période, incluse. Par défaut, la date du jour.

Réponse

ParamètreTypeDescription
insurerCodestringLe Code Assureur actuellement porté par le profil.
profileNamestringNom du profil.
profileUuidstringIdentifiant du profil, la valeur à passer en profile_uuid.
investmentPoolUuidstringBassin d’investissement utilisé par le profil.
inceptionDatestringDate d’inception du profil, sa première réallocation exécutée.
startDatestringDébut de période effectivement appliqué.
endDatestringFin de période effectivement appliquée.
performancesobjectLes six courbes de performance. Voir ci-dessous.
guaranteedFundsarrayUne entrée par fonds en euros présent dans l’historique d’allocation.
volatilitynumberVolatilité annualisée en %, mesurée sur la courbe nette sur la période.
feeConfigurationsarrayGrilles de frais applicables sur la période.
compositionsarrayRéallocations réellement exécutées pendant la période.
driftedCompositionobjectAllocation réellement détenue en fin de période.

L’objet performances

Toutes les courbes sont en base 100 à la date d’inception et ne sont jamais rebasées sur la date de début demandée. Elles sont restituées telles que calculées et stockées par le PMS.

ParamètreDescription
netPerformance du profil, nette de frais. Toujours présente.
grossPerformance du profil, avant frais. Toujours présente.
netCompositionDatesIdem, calculée sur les dates de saisie des allocations plutôt que sur leur exécution.
grossCompositionDatesIdem, avant frais.
netUnitLinkedPerformance de la seule poche UC, hors fonds en euros.
grossUnitLinkedIdem, avant frais.

L’objet grille de frais

ParamètreTypeDescription
configurationDatestringDate à partir de laquelle cette grille s’applique.
annualFeesnumberFrais de gestion tous supports, par an, en %.
feesUnitLinkedAssetsnumberFrais de gestion sur les UC hors ETF, par an, en %.
feesEtfAssetsnumberFrais de gestion sur les ETF, par an, en %.
feesGuaranteedFundsnumberFrais de gestion sur les fonds garantis, par an, en %.
feesEtfTransactionsnumberCoût d’arbitrage sur ETF, en %.
feesFrequencystringFréquence de prélèvement, par exemple MONTHLY.
feesDeductionDaynumberJour de prélèvement.
feesDeductionMonthnumberMois de prélèvement, lorsque la fréquence l’exige.
feesDeductionWeekDaystringJour de semaine de prélèvement, lorsque la fréquence l’exige.
subscriptionSeriesFeesarrayFrais de souscription définis pour des supports particuliers.

La grille déjà en vigueur à l’ouverture de la période est renvoyée en premier, avec sa configurationDate recalée sur la date de début demandée, afin que vous sachiez toujours quels frais s’appliquaient au début de la période. Les grilles créées ensuite dans la période suivent, par ordre chronologique.

L’objet composition

Seules les réallocations réelles sont renvoyées, identifiées par leur date d’exécution : l’allocation en vigueur avant la période n’est pas répétée, donc une période sans mouvement renvoie un tableau vide.

ParamètreTypeDescription
compositionDatestringDate de saisie de l’allocation.
executionDatestringDate de prise d’effet de l’allocation.
allocationsarrayUne entrée par support, avec son weight en %.

L’objet allocation dérivée

Entre deux réallocations, l’allocation évolue seule au gré des marchés. Ce bloc met le poids décidé lors de la dernière réallocation en regard du poids réellement atteint.

ParamètreTypeDescription
referenceDatestringDate à laquelle les poids dérivés sont observés.
lastExecutionDatestringDate de la réallocation depuis laquelle la dérive est mesurée.
allocationsarrayUne entrée par support, avec weight et driftedWeight en %.

Si aucun de vos profils actifs ne porte cet identifiant, vous recevez un 404 PMS_PROFILE_NOT_FOUND. Un profil appartenant à une autre société de gestion répond de la même manière.

Récupérer les données PRIIPs (EPT) d’un profil

curl \
  --location '{BASE_BACKEND_URL}/pms/api/v1/profiles/priips?profile_uuid=aaaic:aaa_model_portfolios:527&start_date=2016-01-01&end_date=2026-06-30' \
  --header 'Authorization: Bearer <myToken>'

La commande ci-dessus renvoie un JSON structuré comme suit :

{
  "insurerCode": "DYN-01",
  "profileName": "Profil Dynamique",
  "profileUuid": "aaaic:aaa_model_portfolios:527",
  "inceptionDate": "2019-04-01",
  "startDate": "2016-01-01",
  "endDate": "2026-06-30",
  "annualPerformances": {
    "profileNet": [
      { "year": 2020, "performance": 4.12 },
      { "year": 2021, "performance": 11.87 },
      { "year": 2022, "performance": -9.34 }
    ],
    "benchmark": [
      { "year": 2020, "performance": 3.90 },
      { "year": 2021, "performance": 12.10 },
      { "year": 2022, "performance": -9.80 }
    ]
  },
  "eptRecords": [
    {
      "eptDate": "2025-12-31",
      "backfillingProxy": "80% MSCI World (raccordé avant 2015) / 20% Bloomberg Euro Agg",
      "generalPortfolioInformation": {
        "00010_Portfolio_Manufacturer_Name": "AM INVEST ASSET MANAGEMENT",
        "00015_Portfolio_Manufacturer_Group_Name": "AM INVEST",
        "00016_Portfolio_Manufacturer_LEI": "969500XXXXXXXXXXXX34",
        "00030_Portfolio_Identifying_Data": "DYN-01",
        "00040_Type_Of_Identification_Code_For_The_Fund_Share_Or_Portfolio": 99,
        "00050_Portfolio_Name": "Profil Dynamique",
        "00060_Portfolio_Or_Share_Class_Currency": "EUR",
        "00070_PRIIPs_KID_Publication_Date": "2026-01-15",
        "00075_PRIIPs_KID_Web_Address": "https://www.example.com/kid/dynamique",
        "00080_Portfolio_PRIIPS_Category": 2
      },
      "riskAssessment": {
        "01010_Valuation_Frequency": 252,
        "01020_Portfolio_VEV_Reference": 12.45,
        "01030_IS_Flexible": false,
        "01040_Flex_VEV_Historical": null,
        "01050_Flex_VEV_Ref_Asset_Allocation": null,
        "01060_IS_Risk_Limit_Relevant": false,
        "01080_Existing_Credit_Risk": false,
        "01090_SRI": 4,
        "01095_IS_SRI_Adjusted": false,
        "01100_MRM": 4,
        "01110_CRM": 1,
        "01120_Recommended_Holding_Period": 8,
        "01140_Liquidity_Risk": "M"
      },
      "performanceScenarios": {
        "02010_Portfolio_Return_Unfavourable_Scenario_1_Year": -18.42,
        "02020_Portfolio_Return_Unfavourable_Scenario_Half_RHP": -4.11,
        "02030_Portfolio_Return_Unfavourable_Scenario_RHP_Or_First_Call_Date": -1.22,
        "02040_Portfolio_Return_Moderate_Scenario_1_Year": 3.95,
        "02100_Portfolio_Return_Stress_Scenario_1_Year": -32.10,
        "02130_Portfolio_Number_Of_Observed_Return_M0": 2520,
        "02220_Reference_Invested_Amount": 10000
      },
      "costs": {
        "03010_One_Off_Cost_Portfolio_Entry_Cost": 0.00,
        "03050_One_Off_Costs_Portfolio_Sliding_Exit_Cost_Indicator": false,
        "03060_Ongoing_Costs_Management_Fees_And_Other_Administrative_Or_Operating_Costs": 1.72,
        "03080_Ongoing_Costs_Portfolio_Transaction_Costs": 0.11,
        "03095_Incidental_Costs_Portfolio_Performance_Fees": 0.00,
        "feesDelegatedPortfolioManagementUnitLinked": 0.80,
        "feesDelegatedPortfolioManagementEtf": 0.40,
        "feesDelegatedPortfolioManagementGuaranteedFunds": 0.00
      },
      "displayedCostsAndRiy": {
        "07010_Total_Cost_1_Year_Or_First_Call": 183.00,
        "07020_RIY_1_Year_Or_First_Call": 1.83,
        "07030_Total_Cost_Half_RHP": 780.00,
        "07040_RIY_Half_RHP": 1.81,
        "07050_Total_Cost_RHP": 1620.00,
        "07060_RIY_RHP": 1.80
      }
    }
  ]
}

Cet endpoint renvoie les données réglementaires de l’un de vos profils : ses performances annuelles calendaires et chaque EPT enregistré sur la période, découpé en cinq blocs standard.

Requête HTTP

GET /pms/api/v1/profiles/priips

Paramètres de requête

ParamètreObligatoireTypeDescription
profile_uuidouistringIdentifiant unique du profil, tel que renvoyé dans le champ profileUuid.
start_datenonstringDébut de la période, inclus. Par défaut, la date d’inception du profil.
end_datenonstringFin de la période, incluse. Par défaut, la date du jour.

Réponse

ParamètreTypeDescription
insurerCodestringLe Code Assureur actuellement porté par le profil.
profileNamestringNom du profil.
profileUuidstringIdentifiant du profil, la valeur à passer en profile_uuid.
inceptionDatestringDate d’inception du profil.
startDatestringDébut de période effectivement appliqué aux EPT.
endDatestringFin de période effectivement appliquée aux EPT.
annualPerformancesobjectPerformances annuelles calendaires du profil et de son indice de référence.
eptRecordsarrayUne entrée par EPT dont la date tombe dans la période, par ordre chronologique.

L’objet annualPerformances

ParamètreTypeDescription
profileNetarrayPerformances annuelles du profil, nettes de frais, sous la forme { year, performance } en %.
benchmarkarrayIdem sur l’indice de référence. Null si aucun benchmark n’est configuré sur le profil.

L’objet enregistrement EPT

ParamètreTypeDescription
eptDatestringDate de l’EPT.
backfillingProxystringTexte libre décrivant l’indice composite utilisé pour prolonger l’historique du profil lorsqu’il est plus court que la profondeur exigée par PRIIPs.
generalPortfolioInformationobjectQui produit le profil, sous quel nom et quelle devise, et où trouver son DIC.
riskAssessmentobjectNiveau de risque réglementaire, dont l’indicateur SRI noté de 1 à 7.
performanceScenariosobjectLes quatre scénarios de marché réglementaires et les statistiques dont ils découlent.
costsobjectTous les frais supportés par l’épargnant, à l’entrée, en cours de vie et à la sortie.
displayedCostsAndRiyobjectLes frais tels qu’affichés dans le DIC, en euros et en réduction du rendement.

Si aucun de vos profils actifs ne porte cet identifiant, vous recevez un 404 PMS_PROFILE_NOT_FOUND. Un profil appartenant à une autre société de gestion répond de la même manière.

Erreurs

L’API Coanda utilise les codes d’erreur suivants:

4xx

Code d’erreurSignification
401Unauthorized – Le token n’est pas valide.
403Forbidden – Le token est valide mais pas les permissions associées.
404Not Found – Le endpoint demandé n’existe pas.
405Method Not Allowed – La méthode HTTP spécifié n’est pas supportée.
422Bad Request – La requête est invalide.
429Too Many Requests – Trop de requêtes envoyées d’un coup. Ralentissez !

5xx

Error CodeMeaning
500Internal Server Error – Erreur générique coté serveur. Réessayez plus tard.
503Service Unavailable – Service en maintenance. Réessayez plus tard.

Module PMS

Les endpoints du Module PMS renvoient, en plus du statut HTTP, un code métier dans le champ code du corps d’erreur.

CodeStatutSignification
PMS_PROFILE_NOT_FOUND404Aucun profil actif ne porte ce Code Assureur dans votre périmètre.
PMS_PROFILE_CODE_NOT_UNIQUE400Plusieurs profils actifs portent ce Code Assureur : le serveur n’en choisit jamais un.
PMS_INVESTMENT_POOL_NOT_FOUND404Ce bassin d’investissement n’existe pas.
PMS_INVESTMENT_POOL_NOT_OWNED403Ce bassin d’investissement n’appartient pas à votre société de gestion et ne lui est pas affecté.
PMS_INVALID_DATE_RANGE400La date de fin est antérieure à la date de début. Une date de fin absente vaut la date du jour.