Documentation

    REST API (on premise)

    AICopy for LLM

    On-Premise REST API Overview

    The on-premise REST API functions similarly to the cloud version, with some differences detailed below.

    Enabling the API

    By default, the API is disabled. It will only be enabled when you add a REST_KEY environment variable.

    Authentication

    To authenticate your requests to the REST API, add an Authorization header set to the value you provided in the REST_KEY environment variable.

    The Visitor Object

    The Visitor object may differ slightly in the on-premise version, depending on your configuration. Most attributes will be present, and all Visitors will have the same properties.

    Session IDs

    The watch link and viewer token endpoints return a session_id like onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4. Your instance generates it, so it needs no connection to our servers. Keep it: it's what you pass back to request the Session's recording.

    Endpoints

    On-premise, the REST API is mounted on the /api path of your base endpoint. For example, if your BASE_ENDPOINT is https://support.acmetech.com/cobrowsing, one of the endpoints will be https://support.acmetech.com/cobrowsing/api/visitors/list/latest.

    Listing the Latest Visitors

    Use this endpoint to list the latest online Visitors. This only works with MongoDB.

    GET /v1.4/visitors/list/latest
    
    ParameterTypeDescription
    max_resultsnumber, optionalThe max number of results to return.

    Response

    // HTTP 200
    {
      "status": "ok",
      "visitors": [
        {
          "short_id": "1234",
          // ...
        }
      ]
    }
    
    FieldTypeDescription
    visitorsVisitor[]List of Visitors matching the query.

    Searching for a Visitor

    Use this endpoint to search for Visitors.

    GET /v1.4/visitors/list/search
    
    ParameterTypeDescription
    qstring, optionalThe search query in this format. If left empty, the latest Visitors will be returned.
    max_resultsnumber, optionalThe max number of results to return.

    Response

    // HTTP 200
    {
      "status": "ok",
      "visitors": [
        {
          "short_id": "1234",
          // ...
        }
      ]
    }
    
    FieldTypeDescription
    visitorsVisitor[]List of Visitors matching the query.

    Retrieving a Visitor

    Use this endpoint to retrieve a specific Visitor.

    GET /v1.4/visitors/{visitor_id}
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.
    includeHistoryboolean, optionalSet to true to include the Visitor's pageview history (MongoDB only).

    Response

    // HTTP 200
    {
      "status": "ok",
      "visitor": {
        "short_id": "1234",
        "history": [
          // Pageviews, if includeHistory was set to true
        ],
        // ...
      }
    }
    
    FieldTypeDescription
    visitorVisitorThe Visitor.
    visitor.historyPageview[], optionalThe Visitor's latest pageviews. Only present with includeHistory.

    Errors

    CodeDescription
    404The Visitor does not exist.

    Generating a Viewer Token to Embed Co-Browsing

    Use this endpoint to generate a viewer token instead of a watch link. The token lets you embed the co-browsing screen directly in your own application with the viewer SDK, instead of opening the hosted watch page. The Visitor's browser is asked to prepare for the Session right away, so only request a token when the viewer is about to connect.

    // POST /v1.4/visitors/{visitor_id}/viewer_token
    {
      "licenseToken": "token1234",
      "permissions": {},
      "viewer": {
        "id": "123",
        "name": "Joe Smith"
      }
    }
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.
    licenseTokenstringThe token obtained from here. Reach out to our team if this is incompatible with your flow for alternative options.

    The endpoint also accepts the same viewer, agent, permissions and session_properties parameters as the watch link endpoint above.

    Response

    // HTTP 200
    {
        "status": "ok",
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....",
        "endpoint": "https://support.acmetech.com/cobrowsing",
        "region": "onpremise",
        "short_id": "1234",
        "session_id": "onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4",
        "expiration": "2026-01-11T18:01:49.700Z"
    }
    
    FieldTypeDescription
    tokenstringThe token to pass to the viewer SDK.
    endpointstringThe server the viewer should connect to (your on-premise instance).
    regionstringAlways onpremise.
    short_idstringThe short id of the Visitor.
    session_idstringThe id of the Session this token starts. Use it to request the Session's recording.
    expirationDatetime (ISO 8601)Time at which the token is no longer valid. It's 60 seconds after issue unless you set X-Token-Expiry-Seconds. Use it right away.

    Errors

    CodeDescription
    400A required parameter is missing or invalid.
    402This viewer would put you over your subscription limits.
    404The Visitor does not exist.
    409The Visitor's browser is not supported.

    Requesting a Session Recording

    Renders an ended Session to MP4 on your own instance. See Session Recording for the storage and Chromium setup it needs.

    This Endpoint Authenticates Differently
    This one does not use REST_KEY. Send an Authorization: Bearer header holding a short-lived HS256 JWT signed with your SECRET_KEY, with the payload {"scope": "cobrowsing-data-call", "apiKeys": "*"}.
    // POST /v1.4/recordings/{visitor_id}
    {
      "session_id": "onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4"
    }
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.
    session_idstringThe session_id returned when you generated the watch link or viewer token.
    webhook_urlstring, optionalAn http or https URL the outcome is POSTed to when the render finishes, so you don't have to poll for it.
    clear_errorboolean, optionalDiscards a failure remembered from an earlier attempt and starts a fresh render. See Failed Renders.

    Rendering is asynchronous. The first request starts it, and further requests report progress until the video is ready. Poll about once a minute rather than tightly, as rendering a long Session takes a while.

    Response

    // HTTP 200, still rendering
    {
        "status": "ok",
        "video_status": "recording"
    }
    
    // HTTP 200, finished
    {
        "status": "ok",
        "video_status": "ready",
        "video_url": "https://support.acmetech.com/cobrowsing/recordings/APIKEY/1234/6f1b....mp4"
    }
    
    FieldTypeDescription
    video_statusstringrecording while the render is in progress, ready once the video is available.
    video_urlstringPresent when video_status is ready. Points at your own storage. Held for 6 hours after the render completes.

    Failed Renders

    A render that fails is remembered for 6 hours, so a poll doesn't silently start the whole thing over. Within that window every request for the Session reports the same failure, in the standard REST error shape:

    // HTTP 422
    {
        "success": false,
        "status": "error",
        "error": "recording_failed",
        "error_explained": "Recording this session failed. Retry it with clear_error."
    }
    
    FieldTypeDescription
    errorstringWhy the render failed, from the closed set below. This is the field to branch on.
    error_explainedstringA human-readable description. Meant for logs and support tickets, not for your code: the wording can change between releases.
    successbooleanAlways false. Kept for older clients; status carries the same information.

    The response that first reports a failure carries the status code that fits it (404 when the Session has no events, 501 when your instance can't render it at all). The polls after it come back as 422 with the same error, which is why a 404 can turn into a 422 for the same Session. Branch on error, not on the status code.

    To try again, send the same request with clear_error. The remembered failure is discarded and a new render starts, so the response is the usual video_status: "recording":

    // POST /v1.4/recordings/{visitor_id}
    {
      "session_id": "onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4",
      "clear_error": true
    }
    

    Retrying only helps for the codes marked retriable. The rest fail the same way until something changes about the Session or your instance:

    errorMeaningRetriable
    recording_failedThe render failed for a reason we can't attribute. The underlying error is in your instance's logs.Yes, though often the same way twice
    browser_crashedThe Chromium container dropped the replay part-way through.Yes
    recording_timed_outThe replay or the encode didn't finish in time.Yes
    recording_lostThe instance running the render went away, and it couldn't be picked back up within two hours.Yes
    upload_failedThe video rendered, but couldn't be written to your storage. Check the bucket, credentials or mounted volume.After fixing storage
    no_events_foundNo events were stored for this Session, so there is nothing to render.No
    no_browser_configuredThe Session needs a browser and CHROMIUM_ENDPOINT is unset.After setting CHROMIUM_ENDPOINT
    not_implementedMongoDB is disabled on this instance, so no Session events were stored to replay.After enabling MONGO_URI
    visitor_not_foundThe Visitor does not exist. Sent as user_not_found to v1.0 and v1.2 clients.No

    A 503 with "error": "server_busy" is not a failed render: every render slot is in use and nothing has been given up on. Retry the same request in a few seconds, without clear_error.

    Being Told When It's Done

    Pass webhook_url and the outcome is POSTed there as JSON when the render settles, instead of you having to poll for it. Both outcomes name the Session and Visitor they are about. A finished render carries the same fields as the successful response; a failed one carries only status and error, not the success and error_explained a REST error body has:

    // POST to your webhook_url, once the render finishes
    {
        "status": "ok",
        "video_status": "ready",
        "video_url": "https://support.acmetech.com/cobrowsing/recordings/APIKEY/1234/6f1b....mp4",
        "session_id": "onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4",
        "short_id": "1234"
    }
    
    // or, when it failed
    {
        "status": "error",
        "error": "browser_crashed",
        "session_id": "onprem_s_3f2c8a1e-9d47-4b02-8f61-05c7ae13d9b4",
        "short_id": "1234"
    }
    

    Any 2xx counts as delivered. Anything else is retried up to five times with a growing delay, then given up on: your instance has no durable job queue, so a receiver that stays down for the length of the retries loses the notification. Polling remains the reliable channel, and the webhook_url is remembered across a re-triggered render.

    Errors

    CodeDescription
    400session_id is missing, or webhook_url is not a valid http/https URL.
    404The Visitor does not exist, or no events were recorded for this Session.
    422An earlier attempt at this Session failed. See Failed Renders.
    501MongoDB is disabled on your instance, or the Session needs a browser and CHROMIUM_ENDPOINT is unset.
    503Every render slot is in use. Retry in a few seconds.

    Preparing a Session

    Use this endpoint to ask the Visitor's browser to prepare for a Session ahead of time, so the Session starts faster. This is done automatically when you generate a watch link.

    POST /v1.4/visitors/{visitor_id}/session/prepare
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.

    Response

    // HTTP 200
    {
      "status": "ok"
    }
    

    Errors

    CodeDescription
    404The Visitor does not exist.

    Stopping an Active Session

    Use this endpoint to stop the Visitor's active Session.

    DELETE /v1.4/visitors/{visitor_id}/session
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.

    Response

    // HTTP 200
    {
      "status": "ok",
      "visitor": {
        "short_id": "1234",
        // ...
      }
    }
    
    FieldTypeDescription
    visitorVisitorThe Visitor.

    Errors

    CodeDescription
    404The Visitor does not exist.

    Deleting a Visitor

    Use this endpoint to delete a Visitor entirely, including their pageview history and Session recordings. You can only delete Visitors who are not currently online or in a Session.

    DELETE /v1.4/visitors/{visitor_id}
    
    ParameterTypeDescription
    {visitor_id}stringThe short id of the Visitor.

    Response

    // HTTP 200
    {
      "status": "ok"
    }
    

    Errors

    CodeDescription
    404The Visitor does not exist.
    409The Visitor is online or in a Session.

    Deleting All Visitors

    Use this endpoint to delete all Visitors, along with their pageview history and Session recordings.

    DELETE /v1.4/visitors
    

    Response

    // HTTP 200
    {
      "status": "ok"
    }