# Create an analytics key

> Generate a public key for players to send events, or a read-only secret key for a dashboard or MCP client to query a hosted Chunkify Analytics server. Save secret keys when returned. Requires a team owner and a Team Access Key.

```json
{
  "path": "/projects/{projectId}/analytics/connections/{connectionId}/keys",
  "method": "post",
  "schema": {
    "description": "Generate a public key for players to send events, or a read-only secret key for a dashboard or MCP client to query a hosted Chunkify Analytics server. Save secret keys when returned. Requires a team owner and a Team Access Key.",
    "operationId": "createAnalyticsKey",
    "parameters": [
      {
        "description": "The owning Chunkify project ID.",
        "in": "path",
        "name": "projectId",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      {
        "description": "The saved analytics connection ID.",
        "in": "path",
        "name": "connectionId",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    ],
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/AnalyticsKeyCreateParams"
          }
        }
      },
      "required": true
    },
    "responses": {
      "201": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/AnalyticsKeyCreateResponse"
            }
          }
        },
        "description": "New key, returned once."
      },
      "400": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorValidation"
            }
          }
        },
        "description": "Validation error."
      },
      "401": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorAuthentication"
            }
          }
        },
        "description": "Authentication error."
      },
      "403": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorForbidden"
            }
          }
        },
        "description": "Forbidden error."
      },
      "404": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorNotFound"
            }
          }
        },
        "description": "NotFound error."
      },
      "409": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorConflict"
            }
          }
        },
        "description": "The name is already used, setup is incomplete, or deletion needs reconciliation."
      },
      "503": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ResponseErrorServiceUnavailable"
            }
          }
        },
        "description": "The analytics server is unavailable or returned an incompatible response."
      }
    },
    "security": [
      {
        "TeamAccessToken": []
      }
    ],
    "summary": "Create an analytics key",
    "tags": [
      "Analytics Connections"
    ],
    "x-codeSamples": [
      {
        "lang": "typescript",
        "source": "import Chunkify from '@chunkify/chunkify';\n\nconst client = new Chunkify({\n  teamAccessToken: 'My Team Access Token',\n});\n\nconst result = await client.projects.analytics.connections.keys.create(\n  'proj_example',\n  'anc_example',\n  {\n    purpose: 'read',\n  },\n);\n"
      },
      {
        "lang": "python",
        "source": "from chunkify import Chunkify\n\nclient = Chunkify(\n    team_access_token=\"My Team Access Token\",\n)\n\nresult = client.projects.analytics.connections.keys.create(\n    \"proj_example\",\n    \"anc_example\",\n    purpose='read',\n)\n"
      },
      {
        "lang": "php",
        "source": "\u003c?php\n\nuse Chunkify\\Client;\n\n$client = new Client(\n    teamAccessToken: 'My Team Access Token',\n);\n\n$result = $client-\u003eprojects-\u003eanalytics-\u003econnections-\u003ekeys-\u003ecreate(\n    'proj_example',\n    'anc_example',\n    purpose: 'read',\n);\n"
      },
      {
        "lang": "golang",
        "source": "package main\n\nimport (\n\t\"context\"\n\t\"github.com/chunkifydev/chunkify-go\"\n\t\"github.com/chunkifydev/chunkify-go/option\"\n)\n\nfunc main() {\n\tclient := chunkify.NewClient(\n\t\toption.WithTeamAccessToken(\"My Team Access Token\"),\n\t)\n\t_, err := client.Projects.Analytics.Connections.Keys.New(\n\t\tcontext.TODO(),\n\t\t\"proj_example\",\n\t\t\"anc_example\",\n\t\tchunkify.ProjectAnalyticsConnectionKeyNewParams{\n\t\t\tPurpose: chunkify.ProjectAnalyticsConnectionKeyNewParamsPurposeRead,\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n"
      }
    ]
  }
}
```



```json #/components/schemas/ResponseErrorNotFound
{
  "description": "Error response",
  "properties": {
    "error": {
      "description": "Error response details",
      "properties": {
        "code": {
          "const": 404,
          "description": "Code is the HTTP status code",
          "examples": [
            404
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "Ressource not found"
          ],
          "type": "string"
        },
        "type": {
          "const": "NotFoundError",
          "description": "Type indicates the error category",
          "enum": [
            "NotFoundError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ],
  "type": "object"
}
```



```json #/components/schemas/ResponseErrorConflict
{
  "description": "Error response",
  "properties": {
    "error": {
      "description": "Error response details",
      "properties": {
        "code": {
          "const": 409,
          "description": "Code is the HTTP status code",
          "examples": [
            409
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "source_unavailable: the original video is no longer accessible"
          ],
          "type": "string"
        },
        "type": {
          "const": "ConflictError",
          "description": "Type indicates the error category",
          "enum": [
            "ConflictError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ],
  "type": "object"
}
```



```json #/components/schemas/ResponseErrorServiceUnavailable
{
  "properties": {
    "error": {
      "description": "Error response details",
      "properties": {
        "code": {
          "const": 503,
          "description": "Code is the HTTP status code",
          "examples": [
            503
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "The service is temporarily unavailable; retry the request"
          ],
          "type": "string"
        },
        "type": {
          "const": "ServiceUnavailableError",
          "description": "Type indicates the error category",
          "enum": [
            "ServiceUnavailableError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ]
}
```



```json #/components/schemas/AnalyticsKeyCreateParams
{
  "additionalProperties": false,
  "description": "Create the missing key for this purpose. Each hosted connection has at most one player, read-only API and MCP key. Rotate an existing key instead of creating another.",
  "properties": {
    "purpose": {
      "description": "Purpose distinguishes player ingestion, read-only API access and a separate read-only MCP credential. Read and MCP keys have the same collector permissions.",
      "enum": [
        "player",
        "read",
        "mcp"
      ],
      "type": "string"
    }
  },
  "required": [
    "purpose"
  ],
  "type": "object",
  "x-reject-null-fields": [
    "purpose"
  ],
  "x-reject-unknown-fields": true
}
```



```json #/components/schemas/AnalyticsKeyCreateResponse
{
  "properties": {
    "data": {
      "$ref": "#/components/schemas/AnalyticsKey"
    },
    "key": {
      "description": "Key is the new credential. Save read and MCP keys now; later reads omit their values. Public keys remain available.",
      "type": "string"
    },
    "status": {
      "const": "success",
      "type": "string"
    }
  },
  "required": [
    "status",
    "data",
    "key"
  ],
  "type": "object"
}
```



```json #/components/schemas/AnalyticsKey
{
  "description": "One key per purpose. Public player values remain available; read and MCP values are returned only on creation or rotation.",
  "properties": {
    "id": {
      "description": "Id identifies this key in the collector.",
      "type": "string"
    },
    "public_key": {
      "description": "PublicKey is the browser ingestion credential for a player key. Omitted for read-only API and MCP keys, whose secret values are shown once.",
      "type": "string"
    },
    "purpose": {
      "description": "Purpose distinguishes player ingestion, read-only API access and a separate read-only MCP credential. Read and MCP keys have the same collector permissions.",
      "enum": [
        "player",
        "read",
        "mcp"
      ],
      "type": "string"
    }
  },
  "required": [
    "id",
    "purpose"
  ],
  "type": "object"
}
```



```json #/components/schemas/ResponseErrorValidation
{
  "properties": {
    "error": {
      "properties": {
        "code": {
          "const": 400,
          "description": "Code is the HTTP status code",
          "examples": [
            400
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "Invalid request parameters"
          ],
          "type": "string"
        },
        "type": {
          "const": "ValidationError",
          "description": "Type indicates the error category",
          "enum": [
            "ValidationError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ]
}
```



```json #/components/schemas/ResponseErrorAuthentication
{
  "description": "Error response",
  "properties": {
    "error": {
      "description": "Error response details",
      "properties": {
        "code": {
          "const": 401,
          "description": "Code is the HTTP status code",
          "examples": [
            401
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "Authentication error: invalid token or subscription inactive"
          ],
          "type": "string"
        },
        "type": {
          "const": "AuthenticationError",
          "description": "Type indicates the error category",
          "enum": [
            "AuthenticationError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ],
  "type": "object"
}
```



```json #/components/schemas/ResponseErrorForbidden
{
  "properties": {
    "error": {
      "description": "Error response details",
      "properties": {
        "code": {
          "const": 403,
          "description": "Code is the HTTP status code",
          "examples": [
            403
          ],
          "type": "integer"
        },
        "message": {
          "description": "Message is a human-readable error description",
          "examples": [
            "Unauthorized to perform this action"
          ],
          "type": "string"
        },
        "type": {
          "const": "ForbiddenError",
          "description": "Type indicates the error category",
          "enum": [
            "ForbiddenError"
          ],
          "type": "string"
        }
      },
      "required": [
        "type",
        "code",
        "message"
      ],
      "type": "object"
    },
    "status": {
      "const": "error",
      "description": "Status indicates the response status \"error\"",
      "type": "string"
    }
  },
  "required": [
    "status",
    "error"
  ]
}
```