NAV
shell

Introduction

To join a CrowdLIVE you will need the following information:

API Request Authorization

CrowdLIVE expects the x-bleachr account identifier to be included in all API requests to the server in a header that looks like the following:

x-bleachr: account_identifier

curl "https://dev.api.appcats.com/api/v4/broadcast_events_access_code?access_code=(code)" \
  -X POST\ 
  -H "x-bleachr: ${your account identifier}"

User Authentication Token

Each person connected to a CrowdLIVE needs an auth token to join the CrowdLIVE event.

To generate the auth token for a user, your application needs to provide

curl "https://dev.api.appcats.com/api/v4/fans/external_registration" \
  -X POST\ 
  -H "x-bleachr: ${your account identifier}"
  -d '{"id": "6d47a549-b37e-48e1-8cf7-18aee6fd3a19", "name": "APPCAT Dan", "photo_url":""}'  

Make sure to replace the account identifier with yours.

HTTP Request

POST https://dev.api.appcats.com/api/v4/fans/external_registration

Body Parameters

Parameter Description
id A string or integer to identify this user. Each user in a CrowdLIVE needs a unique ID value. This ID value should be consistent for each user while using CrowdLIVE
name The display name of the user to be shown in CrowdLIVE
photo_url The profile photo used while a user does not have their camera on in CrowdLIVE

Fetching a broadcast id

Broadcast IDs can be fetched one of two ways

curl "https://dev.api.appcats.com/api/v4/trending_broadcasts?page=\(page)&per_page=\(perPage)" \
  -H "x-bleachr: ${your account identifier}"

All APPCAT API requests return a JSON object with a "data" list of the requested and "meta" object containing metadata structured like this:

{
    "data":
    [
        {
            "broadcast_score": "6082",
            "id": "608f0bfc-de7f-4c7b-b8ab-23616f2543db",
            "organizer":
            {
                "fan_id": "6d47a549-b37e-48e1-8cf7-18aee6fd3a19",
                "fan_profile_photo": "https://res.cloudinary.com/bleachr/image/upload/v1644958058/account/bleachr/i6d47a549-b37e-48e1-8cf7-18aee6fd3a19_20220246144737.jpg",
                "full_name": "Dan",
                "priority": 1,
                "streamer_id": 500377,
                "verified_voice": true,
                "verified_voice_image_url": "https://res.cloudinary.com/bleachr/image/upload/v1632430749/logosanstext_a0sr6y.png"
            },
            "preview_url": "https://s3.amazonaws.com/cvl-media-dev/608f0bfc-de7f-4c7b-b8ab-23616f2543db/broadcast-video-preview/1691422795.mp4",
            "team":
            {
                "broadcast_ad_config":
                {
                    "number_of_ads_per_ad_break": 0,
                    "number_of_minutes_between_ad_breaks": 30,
                    "show_ad_on_connect": false
                },
                "id": "c831dafe-74a5-4d84-bd79-0edbf4896190",
                "logo": "https://res.cloudinary.com/bleachr/image/upload/v1599855047/Bleachr/DEV/avatars/hawk.jpg",
                "name": "Test Team",
                "nickname": "Test Team",
                "radio_stream_url": null,
                "ticketing_fee_type": null,
                "ticketing_fee_value": null,
                "ticketing_header_image_url": null,
                "ticketing_header_text": null,
                "ticketing_purchase_image_url": null,
                "ticketing_upgrade_barcode_note": null,
                "ticketing_upgrade_note": null
            },
            "theme_config":
            {
                "cover_image_url": null,
                "name": "Dan Public",
                "schedule_icon": null
            },
            "thumbnail_url": "https://s3.amazonaws.com/cvl-media-dev/608f0bfc-de7f-4c7b-b8ab-23616f2543db/broadcast-screenshot/1691422915.png",
            "type": "crowdview",
            "viewer_count": 0
        }
    ],
    "meta":
    {
        "pagination":
        {
            "page": 1,
            "per_page": 10,
            "total": 1,
            "total_pages": 1
        }
    }
}

This endpoint retrieves all active and public CrowdLIVEs that a user could connect to.

HTTP Request

GET https://dev.api.appcats.com/api/v4/trending_broadcasts?page=\(page)&per_page=\(perPage)

Query Parameters

Parameter Default Description
page 1 Page of public CrowdLIVEs
per_page 25 Number of CrowdLIVEs on each page

Get a CrowdLIVE by passcode

Each CrowdLIVE has a short numeric passcode that a person can use to join a "private" CrowdLIVE that is not featured in the trending list

curl "https://dev.api.appcats.com/api/v4/broadcast_events_access_code?access_code=(code)" \
  -X POST\ 
  -H "x-bleachr: ${your account identifier}"

The above command returns JSON structured like this:

{
    "data":
    {
        "flair_disabled": false,
        "ends_at": "2024-02-07T18:42:49Z",
        "branch_url": "https://bleachrapp.app.link/8LGyGShZGob",
        "broadcast_group_id": null,
        "sponsor_id": null,
        "broadcast_moderation_score": "0.0",
        "viewer_count": 0,
        "is_created_via_admin": true,
        "recording_config": null,
        "warnings_supported": true,
        "account_id": "9650fcd8-7a09-4547-bb9c-9c9b909cd2f1",
        "organizer_fan_id": "ee4301e6-d441-4999-a38a-944bab5b3767",
        "mic_muted_list":
        [],
        "video_config":
        {
            "agora_app_id": "313f679e06e14ab288aa2c230ac56a38",
            "agora_channel_id": "4b9b6bf4-bfa6-4038-9046-b84ebcf3bc01",
            "channel_profile": "broadcast",
            "inject_stream_url": null
        },
        "tip_config":
        {
            "disabled": false
        },
        "mic_request_list":
        [],
        "access_code": "537562",
        "mic_allowed_list":
        [],
        "starts_at": "2022-03-25T17:12:49Z",
        "thumbnail_url": null,
        "in_app_product_id": null,
        "type": "crowdview",
        "hidden": false,
        "current_fan_can_broadcast": false,
        "sponsor":
        {},
        "current_fan_priority": 1,
        "status": "live",
        "preview_url": null,
        "purchase_config":
        {
            "broadcast_ticket_coin_price": null,
            "broadcast_ticket_product_id": null,
            "private_broadcast_ticket_coin_price": null,
            "private_broadcast_ticket_product_id": null
        },
        "emote_disabled": false,
        "feed_id": null,
        "broadcast_score": "36075",
        "chat_config":
        {
            "auto_accept_questions": true,
            "chat_disabled": false,
            "questions_disabled": false,
            "stream_channel_id": "167ff9d3-f160-461f-82ca-b14fa5a8ef3b",
            "stream_channel_type": "broadcast"
        },
        "team_id": "d528545d-6f2a-4269-adae-34c88eed0963",
        "crowdview_config":
        {
            "crowd":
            {},
            "crowd_muted": false,
            "crowd_size_max": 24,
            "crowdview_enabled": true,
            "display": "camera",
            "frontrow":
            {},
            "interview_mode": false,
            "interview_unmuted_fan":
            [],
            "mic_state": "muted_list",
            "nosebleeds":
            {},
            "stage":
            {
                "current_stage": "3f196cb7-479a-4f8d-989c-3a1eb9964675",
                "stages":
                [
                    {
                        "created_at": "2023-07-17T21:33:48.623267Z",
                        "created_by": "admin",
                        "id": "3f196cb7-479a-4f8d-989c-3a1eb9964675",
                        "media_state":
                        {
                            "ready": null
                        },
                        "name": "Active Speaker",
                        "type": "active_speaker",
                        "url": null,
                        "youtube_id": null
                    },
                    {
                        "created_at": "2023-06-22T18:27:26.207110Z",
                        "created_by": "admin",
                        "id": "be3813a9-de2e-4995-adad-c1b04307ff09",
                        "media_state":
                        {
                            "ready": null,
                            "status": "pause"
                        },
                        "name": "Present User",
                        "presented_user":
                        {
                            "fan_id": "7d2ce8e1-b46a-4d6e-9d24-9bcd5a0225c9",
                            "fan_profile_photo": "https://res.cloudinary.com/bleachr/image/upload/v1635915634/account/bleachr/a7d2ce8e1-b46a-4d6e-9d24-9bcd5a0225c9_20211103000033.jpg",
                            "full_name": "jonsung89",
                            "priority": 12,
                            "streamer_id": 500018,
                            "verified_voice": false,
                            "verified_voice_image_url": null
                        },
                        "type": "present_user",
                        "url": null,
                        "youtube_id": null
                    }
                ]
            }
        },
        "sent_upcoming_targeted_alert": false,
        "id": "0af589c2-d8d9-48cd-80d1-aed947914827",
        "theme_config":
        {
            "cover_image_url": null,
            "name": "Bucks Crowdview",
            "schedule_icon": null
        },
        "public_broadcast_event_id": null,
        "team":
        {
            "broadcast_ad_config":
            {
                "number_of_ads_per_ad_break": 0,
                "number_of_minutes_between_ad_breaks": 0,
                "show_ad_on_connect": true
            },
            "id": "d528545d-6f2a-4269-adae-34c88eed0963",
            "logo": "https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Milwaukee_Bucks_logo.svg/1200px-Milwaukee_Bucks_logo.svg.png",
            "name": "Test Team",
            "nickname": "Bucks",
            "radio_stream_url": null,
            "ticketing_fee_type": null,
            "ticketing_fee_value": null,
            "ticketing_header_image_url": null,
            "ticketing_header_text": null,
            "ticketing_purchase_image_url": null,
            "ticketing_upgrade_barcode_note": null,
            "ticketing_upgrade_note": null
        }
    }
}

This endpoint retrieves a broadcast if the passcode matches

HTTP Request

GET https://dev.api.appcats.com/api/v4/broadcast_events_access_code?access_code=(code)

URL Parameters

Parameter Description
access_code The integer passcode of the CrowdLIVE

If the passcode is incorrect you will get a 400 with a response body of:

{"data":"invalid-broadcast_event_acces_code"}

Constructing your CrowdLIVE URL

Now that you have a user token and CrowdLIVE ID you can now build the URL to load CrowdLIVE

https://"${HOST_URL}"/"${CrowdLIVE_ID}"?token="${USER_TOKEN}"&identifier="${ACCOUNT_IDENTIFIER}"

CrowdLIVE Request

https://${HOST_URL}/${CrowdLIVE_ID}?token=${USER_TOKEN}&identifier=${ACCOUNT_IDENTIFIER}

URL Path Components

Path Description
HOST_URL Your CrowdLIVE host URL (provided by the App Cats team)
CrowdLIVE_ID The ID of the CrowdLIVE event the user is connecting to

URL Parameters

Path Description
token The signed token for the user connecting
identifier The ID of the CrowdLIVE event the user is connecting to

This URL can then be loaded into a webview or web browser. If running CrowdLIVE inside of an app controlled webview be sure that mic and camera permissions have already been requested by your application. If using system browser CrowdLIVE will take care of prompting for camera and mic access.

Example Projects

iOS Swift Example

Android Kotlin

Errors

The CrowdLIVE API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- The CrowdLIVE requested is hidden for administrators only.
405 Method Not Allowed -- You tried to access a CrowdLIVE with an invalid method.
406 Not Acceptable -- You requested a format that isn't json.
410 Gone -- The resource requested has been removed from our servers.
429 Too Many Requests -- You're requesting too many resources - slow down!
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.