api-referencePOST
POSThttps://analytics.flowsery.com/analytics/api/v1/goals

Record a custom goal event. Only name is required; visitorUid, sessionUid, metadata, and timezone are optional.

Bearer Token (workspace token or website API key)

Workspace tokens need a website selector

Workspace API tokens can access every website in the workspace. Pass either <code>websiteId</code> or <code>domain</code> so Flowsery knows which website to query or mutate. Website API keys are already scoped to one website, so the selector can be omitted.

Website selector

ParameterTypeDescription
websiteIdstringWebsite ID to use with a workspace API token. Include this field in the JSON body unless you provide domain. Omit when authenticating with a website API key.
domainstringWebsite domain to use with a workspace API token when websiteId is not provided. Include this field in the JSON body. Omit when authenticating with a website API key.

Request body

ParameterTypeDescription
visitorUidstringOptional Flowsery visitor ID, typically sourced from the _fs_vid cookie on your own backend.
sessionUidstringOptional Flowsery session ID, typically sourced from the _fs_sid cookie.
nameREQUIREDstringGoal name (lowercase letters, numbers, underscores, and hyphens; max 64 characters).
metadataobjectOptional custom key-value pairs. Keep to 10 keys or fewer.

Metadata field rules

<strong>Keys:</strong> Only lowercase letters, numbers, underscores (_), and hyphens (-). Max 64 characters.

<strong>Values:</strong> Any string up to 255 characters. HTML and script content is stripped automatically for security.

<strong>Limit:</strong> Up to 10 custom parameters per event.

No existing pageview required

The backend can create the goal record on demand. This endpoint should not be documented as requiring a previously recorded pageview.

Error responses

<strong>400 Bad Request</strong> -- Returned when the payload is invalid.

<strong>404 Not Found</strong> -- Not part of the normal create-goal contract.

Example request (Node.js)
const handler = async (req, res) => {
  const _fs_vid = req.cookies._fs_vid;
  const _fs_sid = req.cookies._fs_sid;

  const response = await fetch(
    "https://analytics.flowsery.com/analytics/api/v1/goals",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${FLOWSERY_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        websiteId: process.env.FLOWSERY_WEBSITE_ID,
        visitorUid: _fs_vid,
        sessionUid: _fs_sid,
        name: "newsletter_signup",
        metadata: {
          name: "Elon Musk",
          email: "musk@x.com",
        },
      }),
    }
  );

  const result = await response.json();
  res.status(200).send("Goal tracked");
};
200
{
  "status": "success",
  "data": [{
    "message": "Goal created successfully"
  }]
}