name: bc-notify-manage-academy-slackintegration description: Use when academy staff need to connect Slack, run manual syncs, and monitor Slack sync health for students/cohorts; do NOT use for generic notifications or non-Slack messaging workflows. requires: []
Skill: Manage Academy Slack Integration
When to Use
Use this skill when the user asks to connect an academy to Slack using manual credentials, manually sync Slack users/channels, or inspect sync status/errors/last sync times. Use it for team-level and individual student/cohort sync actions. Do NOT use it for email/SMS notifications, webhook subscriptions, or unrelated admissions operations.
Concepts
- Slack Team: The Slack workspace linked to one academy.
- User mapping: A Slack user is linked when their Slack profile email matches a student user email in that academy's cohorts.
- Cohort mapping: A Slack channel is linked when the channel
name_normalizedmatches the cohort slug. - Manual sync: Staff-triggered async sync endpoint to force refresh without waiting for automatic jobs.
Workflow
- Verify linked team. Call
GET /v1/notify/slack/teamand filter by academy if needed. - Configure Slack credentials manually. Call
POST /v1/notify/academy/slack/team/<team_id>/credentialswith a Slack bot token and metadata (team_name, optionalapp_id,bot_user_id,authed_user). - Check credentials status. Call
GET /v1/notify/academy/slack/team/<team_id>/credentialsand confirmconfigured=true. - Run manual team syncs. Trigger users and channels sync separately:
POST /v1/notify/academy/slack/team/<team_id>/sync/usersPOST /v1/notify/academy/slack/team/<team_id>/sync/channels
- Run manual individual syncs when needed.
- User:
POST /v1/notify/academy/slack/team/<team_id>/sync/user/<slack_user_id> - Cohort:
POST /v1/notify/academy/slack/team/<team_id>/sync/cohort/<cohort_id>
- User:
- Monitor sync health. Poll:
- Team summary:
GET /v1/notify/academy/slack/team/<team_id>/sync/status - User status:
GET /v1/notify/academy/slack/team/<team_id>/sync/user/<slack_user_id> - Cohort status:
GET /v1/notify/academy/slack/team/<team_id>/sync/cohort/<cohort_id>
- Team summary:
- Fix data source mismatches through admissions endpoints. If sync is incomplete:
- ensure students are in the academy cohort (
/v1/admissions/academy/cohort/user) - ensure cohort slug matches Slack channel name (
/v1/admissions/academy/cohort).
- ensure students are in the academy cohort (
Endpoints
| Action | Method | Path | Headers | Body | Response |
|---|---|---|---|---|---|
| List linked Slack teams | GET | /v1/notify/slack/team |
Authorization |
Query optional: academy=<slug> |
Paginated list of Slack teams |
| Get team credentials status | GET | /v1/notify/academy/slack/team/<team_id>/credentials |
Authorization, Academy: <academy_id> |
— | configured boolean + metadata; token is never returned |
| Configure team credentials | POST/PUT | /v1/notify/academy/slack/team/<team_id>/credentials |
Authorization, Academy: <academy_id> |
token, optional team_name, app_id, bot_user_id, authed_user |
200 configured response |
| Trigger team users sync | POST | /v1/notify/academy/slack/team/<team_id>/sync/users |
Authorization, Academy: <academy_id> |
— | 202 accepted + metadata |
| Trigger team channels sync | POST | /v1/notify/academy/slack/team/<team_id>/sync/channels |
Authorization, Academy: <academy_id> |
— | 202 accepted + metadata |
| Trigger single user sync | POST | /v1/notify/academy/slack/team/<team_id>/sync/user/<slack_user_id> |
Authorization, Academy: <academy_id> |
— | 202 accepted + metadata |
| Get single user sync status | GET | /v1/notify/academy/slack/team/<team_id>/sync/user/<slack_user_id> |
Authorization, Academy: <academy_id> |
— | User-team sync status object |
| Trigger single cohort sync | POST | /v1/notify/academy/slack/team/<team_id>/sync/cohort/<cohort_id> |
Authorization, Academy: <academy_id> |
— | 202 accepted + metadata |
| Get single cohort sync status | GET | /v1/notify/academy/slack/team/<team_id>/sync/cohort/<cohort_id> |
Authorization, Academy: <academy_id> |
— | Cohort-channel sync status object |
| Get team sync status | GET | /v1/notify/academy/slack/team/<team_id>/sync/status |
Authorization, Academy: <academy_id> |
— | Team summary + users/channels counters |
| Manage cohort membership (source data) | GET/POST/PUT/DELETE | /v1/admissions/academy/cohort/user |
Authorization, Academy: <academy_id> |
Depends on method | Cohort-user assignment result |
| Manage cohorts/slugs (source data) | GET/POST/PUT | /v1/admissions/academy/cohort |
Authorization, Academy: <academy_id> |
Depends on method | Cohort object(s) |
Configure team credentials — request (POST /v1/notify/academy/slack/team/<team_id>/credentials):
{
"token": "xoxb-1234567890-abcdef",
"team_name": "4Geeks Academy",
"app_id": "A123456",
"bot_user_id": "U0BOT123",
"authed_user": "U0ADMIN123"
}
Credentials status — response (200):
{
"configured": true,
"team_id": "T01ABC",
"team_name": "4Geeks Academy",
"app_id": "A123456",
"bot_user_id": "U0BOT123",
"authed_user": "U0ADMIN123",
"updated_at": "2026-03-23T18:21:31.123Z"
}
Trigger team users sync — response (202):
{
"status": "accepted",
"sync_type": "users",
"team_id": 7
}
Trigger single user sync — response (202):
{
"status": "accepted",
"sync_type": "user",
"team_id": 7,
"slack_user_id": "U09ABC123"
}
Team sync status — response (200):
{
"id": 7,
"slack_id": "T01ABC",
"name": "4Geeks Academy",
"sync_status": "COMPLETED",
"sync_message": null,
"synqued_at": "2026-03-23T18:21:31.123Z",
"users": {
"total": 120,
"completed": 110,
"incompleted": 10,
"last_synqued_at": "2026-03-23T18:21:30.555Z"
},
"channels": {
"total": 18,
"completed": 15,
"incompleted": 3,
"last_synqued_at": "2026-03-23T18:20:40.111Z"
}
}
Single user status — response (200):
{
"sync_status": "INCOMPLETED",
"sync_message": "Slack user exists but is not linked to this team",
"synqued_at": null
}
GET list note: GET /v1/notify/slack/team is paginated.
For /academy/ endpoints, always send Academy header. Error messages may be translated; send Accept-Language (en, es) to control language.
Edge Cases
- Missing or wrong academy scope: API returns 403 or academy validation error. Retry with correct
Academyheader and permissions. - Team not found in academy: Returns
slack-team-not-found. Use a team id that belongs to the current academy. - User sync stays incomplete: Usually user email does not map to any student in academy cohorts. Fix enrollment/email first, then re-run user sync.
- Cohort sync stays incomplete: Usually no channel matches cohort slug. Rename channel or cohort slug, then re-run cohort sync.
- Missing Slack credentials: Sync tasks fail if team credentials were not configured for that Slack team.
- Automatic sync exists but not enough: Use manual sync endpoints for targeted recovery or verification.
Checklist
- Confirm academy Slack team exists (
GET /v1/notify/slack/team). - Configure credentials via
POST /v1/notify/academy/slack/team/<team_id>/credentials. - Verify
configured=trueusingGET /v1/notify/academy/slack/team/<team_id>/credentials. - Trigger team users/channels sync and verify
202accepted responses. - Trigger individual user/cohort sync for failed mappings.
- Poll team and individual status endpoints until completion or clear error.
- Fix admissions source data (cohort memberships/slugs) when status is incomplete.
- Re-run manual sync endpoints and confirm status/messages are healthy.