Test mode

Build and verify a full Koil integration with test-mode keys and magic connections, before any provider app is approved.

Test mode is Koil's sandbox. A test-mode API key uses the same /v1 endpoints, schemas, event topics, idempotency rules, pagination, and error envelopes as a live key, against fully isolated infrastructure and simulated providers. Nothing a test-mode key does can reach a real provider or live data.

Keys

Every API key belongs to exactly one mode, and the mode is visible in the key itself: koil_live_… or koil_test_…. Send the full value as the bearer token:

Authorization: Bearer koil_test_...

The prefix makes a key's environment obvious in an env file and lets leak scanners match it, but it is not what decides the mode: Koil checks the prefix against the key's own mode and rejects a mismatch, and an unprefixed value is rejected outright. Both modes belong to the same Organization and users; switching to test mode means using a test key, not a separate account. Create keys in the Koil admin console.

Magic connections

Test mode has no OAuth flow. Instead, every Organization can use a fixed catalog of magic connections — the equivalent of test card numbers — each of which stands for a provider grant in a known state:

  • healthy — an active grant carrying every scope any capability needs.
  • expired — a grant that can no longer be refreshed; operations fail as they would after a user revokes access.
  • missing_scopes — an active grant carrying only what profile discovery needs, so the profile can be listed and connected and every other operation is refused with scope_insufficient.

Use one exactly where you would use a real connectionId: list its eligible profiles, then create a Connected Profile from one of them. The Quickstart walks through it.

curl "https://api.koil.co/v1/connections/test_conn_youtube_healthy/eligible-profiles" \  -H "Authorization: Bearer $KOIL_API_KEY"

Not yet connectable in test mode: Instagram, Facebook

WhatsApp, TikTok, YouTube, Google Business Profile, LinkedIn magic connections can be discovered and connected end to end. For the others, build against a live key with your own app for now:

  • Instagram: Test mode's simulated Graph API lists no Pages, so discovery finds no Instagram account, and Facebook Login's connect step needs a Page token test mode does not mint.
  • Facebook: Test mode's simulated Graph API lists no Pages, so discovery finds none, and connecting a Page needs a Page token test mode does not mint.

The catalog below is generated from the same declarations test mode serves, so every id listed resolves and nothing else does.

Connection idProviderStatusScopes
test_conn_instagram_healthyinstagramactiveinstagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_messages, pages_read_engagement, pages_show_list
test_conn_instagram_expiredinstagraminvalidinstagram_basic, instagram_content_publish, instagram_manage_comments, instagram_manage_messages, pages_read_engagement, pages_show_list
test_conn_instagram_missing_scopesinstagramactiveinstagram_basic, pages_show_list
test_conn_facebook_healthyfacebookactivepages_manage_engagement, pages_manage_metadata, pages_manage_posts, pages_messaging, pages_read_engagement, pages_read_user_content, pages_show_list, publish_video
test_conn_facebook_expiredfacebookinvalidpages_manage_engagement, pages_manage_metadata, pages_manage_posts, pages_messaging, pages_read_engagement, pages_read_user_content, pages_show_list, publish_video
test_conn_facebook_missing_scopesfacebookactivepages_show_list
test_conn_whatsapp_healthywhatsappactivebusiness_management, whatsapp_business_management, whatsapp_business_messaging
test_conn_whatsapp_expiredwhatsappinvalidbusiness_management, whatsapp_business_management, whatsapp_business_messaging
test_conn_whatsapp_missing_scopeswhatsappactivebusiness_management, whatsapp_business_management
test_conn_tiktok_healthytiktokactivebiz.brand.insights, comment.list, comment.list.manage, message.list.read, message.list.send, user.account.type, user.info.basic, user.info.username, video.list, video.publish, video.upload
test_conn_tiktok_expiredtiktokinvalidbiz.brand.insights, comment.list, comment.list.manage, message.list.read, message.list.send, user.account.type, user.info.basic, user.info.username, video.list, video.publish, video.upload
test_conn_tiktok_missing_scopestiktokactiveuser.account.type, user.info.basic, user.info.username
test_conn_youtube_healthyyoutubeactivehttps://www.googleapis.com/auth/youtube.force-ssl
test_conn_youtube_expiredyoutubeinvalidhttps://www.googleapis.com/auth/youtube.force-ssl
test_conn_youtube_missing_scopesyoutubeactivenone
test_conn_google_business_profile_healthygoogle_business_profileactivehttps://www.googleapis.com/auth/business.manage
test_conn_google_business_profile_expiredgoogle_business_profileinvalidhttps://www.googleapis.com/auth/business.manage
test_conn_google_business_profile_missing_scopesgoogle_business_profileactivenone
test_conn_linkedin_healthylinkedinactiver_organization_social, r_organization_social_feed, rw_organization_admin, w_organization_social, w_organization_social_feed
test_conn_linkedin_expiredlinkedininvalidr_organization_social, r_organization_social_feed, rw_organization_admin, w_organization_social, w_organization_social_feed
test_conn_linkedin_missing_scopeslinkedinactiverw_organization_admin

Connect Sessions and POST /v1/connections/import are not available in test mode; they need a real provider app. Build and test everything downstream of the Connection with magic connections, then run the connect flow against your own app in live mode.

What is isolated

Test mode keeps its own database, event delivery, and background workers, so there is no shared state between modes. Every Koil id a test-mode key produces carries a test_ prefix (test_cp_…, test_pub_…, test_med_…), and every delivered event carries metadata.mode — live or test — so a receiver shared between modes can tell them apart.

Provider content reads return deterministic fixture data through the same schemas and pagination rules as live reads.

Limits

Test usage is never billed. Test resources are bounded: each Organization may hold a small number of test Connected Profiles, test workflows run for at most an hour, and test state is disposable and may be reset. So a test-mode publish may be scheduled at most 45 minutes ahead; a later scheduling.at is refused with validation_error.

On this page