Introduction
To join a CrowdLIVE you will need the following information:
User\Fan auth token
Your CrowdLIVE broadcast ID
Your APPCATS account identifier to pass with each request with the header
x-bleachrYour CrowdLIVE Host URL
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
An ID value (string or UUID)
Name
Photo URL
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
- The list of currently active CrowdLIVEs with the
trending_broadcastsend point - Providing a CrowdLIVE's passcode with the
passcodeend point
Get Trending CrowdLIVEs
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
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. |