Signals API
Tracking des signaux d'engagement pour les recommandations personnalisees. Les signaux capturent les comportements de visionnage, les interactions et les preferences pour alimenter le moteur de recommandation.
Base URL : /api/v2/signals
Endpoints
| Methode | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /signals | Enregistrer un signal | Oui |
| POST | /signals/batch | Enregistrer un batch de signaux (max 100) | Oui |
| GET | /signals | Obtenir les signaux (pagine) | Oui |
| GET | /signals/counts | Compteurs agreges par type | Oui |
| GET | /signals/most-viewed | Contenu le plus vu | Oui |
| GET | /signals/recent | Activite recente | Oui |
| GET | /signals/has-viewed/:contentId | Verifier si vu | Oui |
| GET | /signals/progress/:contentId | Progression de visionnage | Oui |
| DELETE | /signals | Effacer l'historique des signaux | Oui |
POST /signals
Enregistrer un signal d'engagement unique.
POST /api/v2/signals
Authorization: Bearer <access_token>
Content-Type: application/json
{
"type": "CONTENT_VIEW_START",
"contentId": "movie-uuid",
"contentType": "MOVIE",
"metadata": {
"source": "home_carousel",
"position": 3
}
}
Reponse 201 Created
{
"id": "signal-uuid",
"type": "CONTENT_VIEW_START",
"contentId": "movie-uuid",
"contentType": "MOVIE",
"profileId": "profile-uuid",
"createdAt": "2025-01-15T10:30:00Z"
}
POST /signals/batch
Enregistrer plusieurs signaux en une seule requete (maximum 100).
POST /api/v2/signals/batch
Authorization: Bearer <access_token>
Content-Type: application/json
{
"signals": [
{
"type": "CONTENT_IMPRESSION",
"contentId": "movie-uuid-1",
"contentType": "MOVIE",
"timestamp": "2025-01-15T10:00:00Z"
},
{
"type": "CONTENT_VIEW_START",
"contentId": "movie-uuid-1",
"contentType": "MOVIE",
"timestamp": "2025-01-15T10:05:00Z"
}
]
}
Reponse 201 Created
{
"recorded": 2,
"failed": 0,
"errors": []
}
GET /signals/counts
Compteurs agreges par type de signal.
GET /api/v2/signals/counts?from=2025-01-01&to=2025-01-31
Authorization: Bearer <access_token>
Reponse 200 OK
{
"counts": {
"CONTENT_IMPRESSION": 1250,
"CONTENT_VIEW_START": 85,
"CONTENT_PROGRESS": 340,
"CONTENT_COMPLETE": 42,
"CONTENT_ABANDON": 18,
"SEARCH_QUERY": 23,
"CATEGORY_BROWSE": 56,
"FAVORITE_ADD": 12,
"FAVORITE_REMOVE": 3
},
"period": {
"from": "2025-01-01T00:00:00Z",
"to": "2025-01-31T23:59:59Z"
}
}
GET /signals/most-viewed
Contenu le plus visionne par le profil.
GET /api/v2/signals/most-viewed?contentType=MOVIE&limit=10
Authorization: Bearer <access_token>
Reponse 200 OK
{
"data": [
{
"contentId": "series-uuid-1",
"contentType": "SERIES",
"title": "Breaking Bad",
"viewCount": 25,
"totalWatchTime": 54000,
"lastViewedAt": "2025-01-15T10:00:00Z"
}
]
}
GET /signals/has-viewed/:contentId
Verifier si un contenu a ete visionne.
GET /api/v2/signals/has-viewed/movie-uuid
Authorization: Bearer <access_token>
Reponse 200 OK
{
"contentId": "movie-uuid",
"hasViewed": true,
"viewCount": 2,
"firstViewedAt": "2025-01-10T20:00:00Z",
"lastViewedAt": "2025-01-14T21:00:00Z",
"completed": true
}
GET /signals/progress/:contentId
Obtenir la progression de visionnage d'un contenu.
GET /api/v2/signals/progress/movie-uuid
Authorization: Bearer <access_token>
Reponse 200 OK
{
"contentId": "movie-uuid",
"contentType": "MOVIE",
"progress": 0.65,
"position": 4680,
"duration": 7200,
"lastUpdatedAt": "2025-01-15T10:30:00Z",
"completed": false
}
DELETE /signals
Effacer l'historique des signaux du profil.
DELETE /api/v2/signals?type=CONTENT_IMPRESSION&before=2025-01-01
Authorization: Bearer <access_token>
Query Parameters
| Parametre | Type | Description |
|---|---|---|
type | string | Supprimer uniquement un type specifique |
before | ISO date | Supprimer uniquement avant cette date |
Reponse 200 OK
{
"message": "Signal history cleared",
"deletedCount": 1250
}
Types de signaux
| Type | Description | Metadata |
|---|---|---|
CONTENT_IMPRESSION | Contenu affiche a l'utilisateur | source, position |
CONTENT_VIEW_START | L'utilisateur a commence a regarder | source |
CONTENT_PROGRESS | Mise a jour de progression | position, duration |
CONTENT_COMPLETE | L'utilisateur a termine le contenu | completionRate |
CONTENT_ABANDON | L'utilisateur a arrete de regarder | position, reason |
SEARCH_QUERY | L'utilisateur a effectue une recherche | query, resultCount |
SEARCH_CLICK | Clic sur un resultat de recherche | query, position |
CATEGORY_BROWSE | Navigation dans une categorie | categoryId |
FAVORITE_ADD | Ajout aux favoris | -- |
FAVORITE_REMOVE | Retrait des favoris | -- |
SHARE | Partage de contenu | platform |
RATING | Evaluation du contenu | rating |
Poids des signaux dans les recommandations
| Signal | Poids |
|---|---|
| Impression | 0.1 |
| Debut de visionnage | 0.3 |
| Completion | 1.0 |
| Ajout aux favoris | 0.8 |
Rate Limits specifiques
| Endpoint | Limite |
|---|---|
| Signal unitaire | 60 / minute |
| Batch de signaux | 10 / minute |
| Endpoints de lecture | 100 / minute |
Bonnes pratiques
Batching des signaux
Pour la performance, regrouper les signaux :
const signalBuffer: Signal[] = [];
function trackSignal(signal: Signal) {
signalBuffer.push({
...signal,
timestamp: new Date().toISOString(),
});
if (signalBuffer.length >= 10) {
flushSignals();
}
}
async function flushSignals() {
if (signalBuffer.length === 0) return;
const signals = [...signalBuffer];
signalBuffer.length = 0;
await api.post('/signals/batch', { signals });
}
// Envoyer aussi lors du dechargement de page
window.addEventListener('beforeunload', flushSignals);
Tracking de progression
Envoyer la progression a intervalles reguliers (toutes les 30 secondes) :
let lastPosition = 0;
player.on(
'timeupdate',
throttle(() => {
const position = Math.floor(player.currentTime);
if (Math.abs(position - lastPosition) >= 30) {
trackSignal({
type: 'CONTENT_PROGRESS',
contentId: currentContentId,
contentType: 'MOVIE',
metadata: { position, duration: Math.floor(player.duration) },
});
lastPosition = position;
}
}, 5000),
);
Codes d'erreur
| Code | HTTP | Description |
|---|---|---|
SIGNAL_001 | 400 | Type de signal invalide |
SIGNAL_002 | 400 | ID de contenu invalide |
SIGNAL_003 | 400 | Batch trop volumineux (max 100) |
SIGNAL_004 | 429 | Rate limit depasse |