# Record reported listening

Source: https://recoupable.dev/docs/api-reference/complete/players/post-players-events

Internal trusted Recoup player transport. Requires its Origin plus signed flow; browser-facing same-origin app proxy forwards to API. Provider and fan attribution come from the stored session. Event UUID makes retries idempotent, listenedMs is capped at 30 seconds and checked against elapsed server time. Recording failures do not stop music.

## POST /api/players/events

Full OpenAPI specification: https://recoupable.dev/docs/spec/players.json

## Authentication

This operation's specification permits a request without authentication.

[Authentication guide](https://recoupable.dev/docs/authentication)

## Operation and referenced schemas

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Recoup API - Release Players",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.recoupable.dev"
    }
  ],
  "paths": {
    "/api/players/events": {
      "post": {
        "summary": "Record reported listening",
        "description": "Internal trusted Recoup player transport. Requires its Origin plus signed flow; browser-facing same-origin app proxy forwards to API. Provider and fan attribution come from the stored session. Event UUID makes retries idempotent, listenedMs is capped at 30 seconds and checked against elapsed server time. Recording failures do not stop music.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "ListeningReceipt fields returned by the release player service.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListeningReceipt"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid authentication or failed provider authorization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          },
          "403": {
            "description": "Workspace, origin, or session access denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          },
          "404": {
            "description": "Player not available",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          },
          "429": {
            "description": "Request rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          },
          "503": {
            "description": "Feature/configuration temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlayerError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "flow",
                  "event"
                ],
                "properties": {
                  "flow": {
                    "type": "string",
                    "maxLength": 2048
                  },
                  "event": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "id",
                      "provider",
                      "event"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "provider": {
                        "type": "string",
                        "enum": [
                          "spotify",
                          "apple_music"
                        ]
                      },
                      "event": {
                        "type": "string",
                        "enum": [
                          "connected",
                          "playing",
                          "paused",
                          "stopped",
                          "track_changed",
                          "skip",
                          "heartbeat",
                          "disconnected"
                        ]
                      },
                      "trackId": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "positionMs": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 86400000,
                        "default": 0
                      },
                      "listenedMs": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 30000,
                        "default": 0
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ListeningReceipt": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "const": true
          },
          "recorded": {
            "type": "boolean",
            "description": "False for an already-recorded retry."
          }
        },
        "required": [
          "success",
          "recorded"
        ]
      },
      "PlayerError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
```
