Connect Bubble to Travis CI through the Bubble API Connector targeting api.travis-ci.com (the legacy travis-ci.org was shut down June 2021). Two shared headers are mandatory on every call: 'Authorization: token YOUR_KEY' (not Bearer — this exact format) and 'Travis-API-Version: 3'. Missing either header causes silent 403 errors or returns v2 response shapes that break Bubble's JSON field detection. For CI health dashboards, a Scheduled Backend Workflow (paid plan) refreshes build status data every 5–10 minutes.
| Fact | Value |
|---|---|
| Tool | Travis CI |
| Category | DevOps & Tools |
| Method | Bubble API Connector |
| Difficulty | Intermediate |
| Time required | 1–2 hours |
| Last updated | July 2026 |
Bubble + Travis CI: a non-technical CI health dashboard powered by the Travis REST API
Travis CI's most natural Bubble use-case falls into two camps, and it is worth knowing which one applies to your project before starting. The first camp: you have a SaaS product that ships code, and you want your non-technical founders, product managers, or customer success team to see whether the current build is green or red without needing Travis CI access. The second camp: you are a Bubble developer who wants to understand whether Travis CI can test or deploy Bubble-exported code. Both are valid, but they involve completely different workflows — the first is an API integration tutorial, the second is a .travis.yml configuration conversation.
This guide covers the first camp: connecting Bubble's API Connector to Travis CI's REST API v3 to display build statuses, branch health, and deployment results in a Bubble app. The integration is technically approachable — Travis CI is a fully hosted SaaS with a clean REST API that needs no server setup, no CSRF token fetching (unlike Jenkins), and no SDK. The only subtlety is the authorization header: Travis CI uses 'token YOUR_TOKEN' rather than the 'Bearer YOUR_TOKEN' format that most modern APIs use. This is a deliberate protocol difference, not a bug — and it catches many developers who copy a 'Bearer' prefix from habit.
The second subtlety is the mandatory Travis-API-Version: 3 header. Travis CI maintains a legacy v2 API response shape for backward compatibility. Without the version header pinned to 3, responses from some endpoints default to v2 field names, and Bubble's JSON path mapping — which you configure during Initialize call — will detect the wrong field structure.
For dashboard use-cases, the recommended pattern is: poll Travis CI on a scheduled basis (every 5–10 minutes), store build results in Bubble's database, and serve the dashboard from Bubble's native database rather than making live API calls for every page load. This reduces WU consumption and keeps your dashboard responsive even when Travis CI's API is slow.
Integration method
The Bubble API Connector calls the Travis CI REST API v3 at https://api.travis-ci.com with two required shared headers: 'Authorization: token {key}' (Private) and 'Travis-API-Version: 3' — both must be present at the API Connector group level.
Prerequisites
- A Travis CI account at travis-ci.com with at least one repository configured (open-source repositories are free; private repositories require Travis CI credits)
- A Travis CI API token — generate it from your account Settings at travis-ci.com → Settings → API Authentication (scroll to bottom of the settings page)
- A Bubble app on any plan for read-only dashboard use-cases; Bubble Starter plan or above for Scheduled Backend Workflows (polling) or inbound webhook use-cases
- The free API Connector plugin by Bubble installed in your app (Plugins → Add plugins → search 'API Connector')
- The name of at least one GitHub organization or username whose repositories you want to display (used in the /owner/{org}/repos endpoint)
Step-by-step guide
Step 1 — Generate your Travis CI API token
Log in to your Travis CI account at travis-ci.com. Click your profile avatar in the top-right corner and select 'Settings' from the dropdown. Scroll to the bottom of the Settings page to the 'API Authentication' section. Click 'Copy token' to copy your personal API token to the clipboard. This token is user-scoped — it grants access to all repositories and organizations visible to your Travis CI account. If you are building a Bubble integration for a specific organization, use the credentials of a service account or bot user scoped to that organization for production use. Save the token in a password manager. Note: this is the one credential you will place in Bubble's API Connector in the next step. Also note that travis-ci.org (the legacy domain) was permanently shut down in June 2021 — all API calls must go to api.travis-ci.com. If you have any old tutorials or examples referencing travis-ci.org, they no longer work.
1// Travis CI API Token location:2// travis-ci.com → your profile avatar (top-right) → Settings3// Scroll to: API Authentication → 'Copy token'45// Important distinctions:6// travis-ci.com → ACTIVE (use this)7// travis-ci.org → DEPRECATED and shut down June 2021 (do not use)89// Token scope: user-scoped (access to all repos/orgs your account can see)10// For production: use a service account token1112// API base URL for all calls:13// https://api.travis-ci.comPro tip: Travis CI API tokens are long-lived user-scoped credentials. For a production Bubble integration that serves internal users, consider creating a dedicated Travis CI service account (a separate travis-ci.com account added to your organization with read-only member access) and using that account's API token. This limits the blast radius if the token is compromised.
Expected result: You have a Travis CI API token copied and saved. You have confirmed your Travis CI account is on travis-ci.com (not the deprecated travis-ci.org). The token appears as a long alphanumeric string in the Settings → API Authentication section.
Step 2 — Install the API Connector and configure the Travis CI API group with both required headers
Open your Bubble app editor and click 'Plugins' in the left sidebar. If the API Connector plugin by Bubble is not already installed, click 'Add plugins,' search for 'API Connector,' and install it (it is free). Return to Plugins → API Connector. Click 'Add another API.' Name this group 'Travis CI.' In the 'Root URL' field, enter https://api.travis-ci.com (no trailing slash). Now add BOTH required shared headers — this is the most critical configuration step, and missing either header is the root cause of most Travis CI integration failures in Bubble. Click 'Add a shared header' twice to create two header rows. Header 1: key = 'Authorization', value = 'token YOUR_TOKEN_HERE' (replace YOUR_TOKEN_HERE with your actual token; the word 'token' is lowercase, followed by a single space, then the token string). Tick the 'Private' checkbox for this header — essential so the token stays on Bubble's servers. Header 2: key = 'Travis-API-Version', value = '3' (no Private checkbox needed — this is a public header). Do not use 'Bearer' as the prefix for the Authorization header. Travis CI's v3 API requires the exact format 'token YOUR_TOKEN' — using 'Bearer YOUR_TOKEN' returns a 403 or sometimes an empty response with no error message, making it very hard to debug.
1// Bubble API Connector — Travis CI group configuration2{3 "api_group_name": "Travis CI",4 "root_url": "https://api.travis-ci.com",5 "shared_headers": [6 {7 "key": "Authorization",8 "value": "token YOUR_TOKEN_HERE",9 "private": true,10 "note": "CRITICAL: 'token' (lowercase) + space + your token. NOT 'Bearer'. NOT 'Token'."11 },12 {13 "key": "Travis-API-Version",14 "value": "3",15 "private": false,16 "note": "Required on all calls. Without this, Travis CI returns v2 response shapes."17 }18 ]19}Pro tip: The Travis-API-Version header is added at the API Connector GROUP level (shared headers), not at the individual call level. This ensures every new call you add to this group automatically includes it. If you add Travis CI calls without this group-level header, some endpoints return v2 response shapes that break Bubble's JSON field detection silently.
Expected result: The Travis CI API group exists in Bubble's API Connector with root URL https://api.travis-ci.com and two shared headers: Authorization (marked Private, value starting with 'token ') and Travis-API-Version (value '3'). No individual calls have been created yet.
Step 3 — Add the 'Get Repositories' call and initialize it
Inside the Travis CI API group, click 'Add call.' Name this call 'Get Org Repos.' Set the method to GET. In the endpoint field, type /owner/{org}/repos (where {org} is a Bubble dynamic parameter). Set 'Use as' to 'Data.' Add URL parameters: 'limit' with example value '100,' and optionally 'include' with example value 'repo.last_build' — this tells Travis CI to embed the last build information in the repo list response, saving you a separate API call per repo. Add a 'sort_by' parameter with value 'last_build_at:desc' to get recently-active repos first. Now provide an example value for the {org} path parameter: enter your actual GitHub organization name or username. Click 'Initialize call.' Bubble fires a real GET request to api.travis-ci.com/owner/YOUR_ORG/repos with both shared headers. If successful, Travis CI returns a repositories list and Bubble detects the nested response fields: repositories (list), each with id, name, slug, description, last_build.state, last_build.number, last_build.branch, last_build.finished_at, and more. If initialization fails with 'There was an issue setting up your call': check that the Authorization header value starts with exactly 'token ' (lowercase t, space), the Travis-API-Version header is present, and your organization name is spelled correctly. Click 'Save.'
1// Bubble API Connector — Travis CI 'Get Org Repos' call2{3 "call_name": "Get Org Repos",4 "method": "GET",5 "endpoint": "/owner/{org}/repos",6 "parameters": [7 { "key": "limit", "value": "100" },8 { "key": "include", "value": "repo.last_build" },9 { "key": "sort_by", "value": "last_build_at:desc" }10 ],11 "use_as": "Data"12}1314// Travis CI v3 response shape:15// {16// "@type": "repositories",17// "repositories": [18// {19// "id": 12345678,20// "name": "my-app",21// "slug": "my-org/my-app",22// "description": "Main application",23// "active": true,24// "last_build": {25// "id": 9876543,26// "number": "127",27// "state": "passed",28// "result": 0,29// "duration": 183,30// "branch": { "name": "main" },31// "finished_at": "2026-07-09T14:22:00Z"32// }33// }34// ]35// }Pro tip: The 'include=repo.last_build' parameter is the key to an efficient one-call dashboard. Without it, you get repository metadata only and would need a separate GET /repo/{id}/builds call for each repository to get its build status — multiplying your WU cost and API call count by the number of repos. Always include this parameter for dashboard use-cases.
Expected result: The 'Get Org Repos' call is initialized. Bubble shows detected fields including 'repositories' as a list, with each item containing name, slug, last_build.state, last_build.branch.name, and last_build.finished_at. The call is set to 'Use as: Data.'
Step 4 — Add the 'Get Repo Builds' call for per-repository build history
Add a second call inside the Travis CI group. Name it 'Get Repo Builds.' Set the method to GET. The endpoint is /repo/{slug}/builds — but there is a critical path-encoding requirement: Travis CI repo slugs are in the format 'owner/repo-name' (for example, 'my-company/my-app'). The forward slash in the slug must be URL-encoded as '%2F' for Bubble's API Connector to correctly construct the URL path. In the endpoint field, enter /repo/{slug}/builds where {slug} is a dynamic parameter. When calling this from a Bubble workflow, the slug value must already be percent-encoded — for example, use 'my-company%2Fmy-app' rather than 'my-company/my-app.' Alternatively, use the numeric Travis CI repository ID (available from the Get Org Repos response as the 'id' field) in the endpoint /repo/{id}/builds — numeric IDs do not require encoding and are more reliable. Add URL parameters: 'limit' with value '25' and 'sort_by' with value 'id:desc'. Set 'Use as' to 'Data.' Click 'Initialize call,' providing a real repo slug (URL-encoded) or repo ID for the test. After initialization, Bubble detects build fields including number, state, branch, commit.message, duration, finished_at.
1// Bubble API Connector — Travis CI 'Get Repo Builds' call2{3 "call_name": "Get Repo Builds",4 "method": "GET",5 "endpoint": "/repo/{slug}/builds",6 "parameters": [7 { "key": "limit", "value": "25" },8 { "key": "sort_by", "value": "id:desc" }9 ],10 "use_as": "Data"11}1213// IMPORTANT: URL encoding for repo slugs14// Repo slug format: 'owner/repo-name'15// When used in path: must encode '/' as '%2F'16// Example:17// Unencoded slug: my-company/my-app18// URL for Bubble: /repo/my-company%2Fmy-app/builds19//20// Alternative: use numeric repo ID instead of slug21// Numeric ID from: repositories[0].id in Get Org Repos response22// No encoding needed: /repo/12345678/builds2324// Travis CI v3 build response:25// {26// "builds": [27// {28// "id": 9876543,29// "number": "127",30// "state": "passed",31// "duration": 183,32// "branch": { "name": "main" },33// "commit": {34// "sha": "a1b2c3d4e5f6...",35// "message": "fix: resolve API timeout issue"36// },37// "finished_at": "2026-07-09T14:22:00Z"38// }39// ]40// }Pro tip: Store the numeric Travis CI repository ID (from the id field in the Get Org Repos response) in your Bubble BuildStatus data type rather than the slug string. This avoids URL encoding issues entirely and keeps your API calls cleaner — /repo/12345678/builds is always unambiguous, while /repo/my-company%2Fmy-app/builds can cause issues if the repo is renamed.
Expected result: The 'Get Repo Builds' call is initialized. Bubble shows detected build fields: builds list, each with number, state, branch.name, commit.sha, commit.message, duration, finished_at. The call uses 'Use as: Data.'
Step 5 — Set up a Scheduled Backend Workflow for CI dashboard polling
Navigate to the Backend Workflows section in Bubble's editor (available on Starter plan and above). Click 'Add a new API Workflow' and name it 'Sync Travis CI Status.' This workflow will run on a schedule to fetch and store Travis CI build data in Bubble's database. First, create a Bubble data type to hold the build data: click Data → Data types → Add a new type → name it 'BuildStatus.' Add fields: repo_name (text), repo_slug (text), repo_id (number), last_build_state (text), last_build_branch (text), last_build_number (text), last_build_duration (number), last_build_finished_at (date). Inside the 'Sync Travis CI Status' Backend Workflow, add these steps: Step 1 — Call the 'Get Org Repos' API Connector call with your organization name. Step 2 — Schedule API Workflow on a list using the result of Step 1 (the repositories list). The sub-workflow for each repository should: search for an existing BuildStatus record where repo_id = current repository's id; if found, update last_build_state, last_build_branch, last_build_finished_at; if not found, create a new BuildStatus record. Schedule the parent 'Sync Travis CI Status' workflow to recur every 600 seconds (10 minutes) by triggering it from an app startup workflow using 'Schedule API Workflow' with a recurs interval. This means Bubble polls Travis CI for your entire org's repo status every 10 minutes and serves the dashboard from its own database — no live API calls on user page loads.
1// Bubble data type: BuildStatus2// Data → Data types → BuildStatus3// Fields:4// repo_name — text5// repo_slug — text6// repo_id — number (use as deduplication key)7// last_build_state — text (passed | failed | errored | canceled | started)8// last_build_branch — text9// last_build_number — text10// last_build_duration — number (seconds)11// last_build_at — date1213// Backend Workflow: Sync Travis CI Status14// Step 1: Call API > Travis CI > Get Org Repos (org = "your-org-name")15// Step 2: Schedule API Workflow on a list16// List: Result of step 1 - repositories17// Workflow to run: Upsert BuildStatus1819// Sub-workflow: Upsert BuildStatus20// Step A: Search for BuildStatus where repo_id = current_repo's id21// Step B (if found): Make changes to BuildStatus:22// last_build_state = current_repo's last_build state23// last_build_branch = current_repo's last_build branch name24// last_build_at = current_repo's last_build finished_at25// Step C (if not found): Create new BuildStatus:26// repo_name = current_repo's name27// repo_id = current_repo's id28// repo_slug = current_repo's slug29// (+ all last_build fields)3031// Schedule recurring:32// Action: Schedule API Workflow33// Workflow: Sync Travis CI Status34// Run at: Current date/time35// Recurs every: 600 secondsPro tip: Travis CI's /owner/{org}/repos endpoint with include=repo.last_build returns the last build status for every repo in a single API call — you only need one API Connector call per sync cycle regardless of how many repositories your org has. This keeps WU consumption low even for organizations with dozens of repositories.
Expected result: The 'Sync Travis CI Status' Backend Workflow exists and is scheduled to run every 10 minutes. BuildStatus records are created or updated in Bubble's database on each run. The last_build_state field reflects the current Travis CI build state for each repository.
Step 6 — Build the Bubble CI dashboard and optionally configure Travis CI webhooks
**Dashboard page:** Create a Bubble page named 'ci-dashboard.' Add a Repeating Group with data type 'BuildStatus' and data source 'Do a search for BuildStatus, sorted by last_build_at descending.' Inside each cell, add: a colored Shape or Icon element (conditional green for 'passed,' red for 'failed,' orange for 'errored,' gray for 'canceled'), a Text element showing Current Cell's BuildStatus's repo_name, a Text element showing Current Cell's BuildStatus's last_build_branch, and a Text element showing Current Cell's BuildStatus's last_build_at formatted as relative time ('3 minutes ago'). Add a 'Last refreshed' text element at the top of the page bound to the most recent BuildStatus's last_build_at value. **Webhook path (optional, paid plan):** To receive real-time build notifications from Travis CI rather than polling, configure Travis CI to deliver webhooks to a Bubble Backend Workflow endpoint. In Bubble: Settings → API → enable 'This app exposes a Workflow API.' Create a Backend Workflow named 'travis-webhook.' Click 'Detect request data' and send a test webhook from Travis CI (in your .travis.yml file, add a notifications.webhooks.urls entry pointing to your Bubble workflow URL). After detection, map the payload fields (repository.name, build.state, build.branch, build.commit.message) to update or create a BuildStatus record. Your Bubble Backend Workflow URL format is: https://your-app.bubbleapps.io/api/1.1/wf/travis-webhook. Note that this endpoint is publicly reachable — Travis CI does not sign its webhook payloads, so add a secret URL path parameter (e.g., ?secret=RANDOM_STRING) to prevent unauthorized posts.
1// Bubble CI dashboard — Repeating Group conditional colors2// Type: BuildStatus | Sort: last_build_at descending34// Status badge element (Shape or Icon)5// Default style: gray (unknown)6// Conditionals:7// When Current Cell's BuildStatus's last_build_state = "passed" → background #22c55e (green)8// When Current Cell's BuildStatus's last_build_state = "failed" → background #ef4444 (red)9// When Current Cell's BuildStatus's last_build_state = "errored" → background #f97316 (orange)10// When Current Cell's BuildStatus's last_build_state = "started" → background #3b82f6 (blue)1112// Optional webhook endpoint URL:13// https://your-app.bubbleapps.io/api/1.1/wf/travis-webhook1415// .travis.yml webhook configuration (for reference only — not Bubble code):16// notifications:17// webhooks:18// urls:19// - https://your-app.bubbleapps.io/api/1.1/wf/travis-webhook?secret=YOUR_SECRET20// on_success: always21// on_failure: always2223// Travis CI webhook payload includes:24// { "repository": { "name": "my-app", "owner_name": "my-org" },25// "branch": "main",26// "state": "passed",27// "build_url": "https://travis-ci.com/...",28// "message": "fix: resolve timeout issue" }Pro tip: Travis CI webhook payloads are not signed with a shared secret by default. Protect your Bubble Backend Workflow endpoint by adding a random string as a URL query parameter (e.g., ?secret=abc123xyz) and adding a 'Terminate this workflow if Parameter secret is not equal to abc123xyz' condition at the top of the workflow. This prevents unauthorized actors from posting fake build events to your Bubble app.
Expected result: The CI dashboard Repeating Group shows all repositories with color-coded build status badges, branch names, and relative timestamps. If webhooks are configured, the dashboard updates in near-real-time after each Travis CI build completion without polling.
Common use cases
Non-technical team CI status dashboard in Bubble
A Bubble internal app displays a color-coded grid of repositories, their last build status (passed, failed, errored, canceled), the branch that was last built, and the time elapsed since the last build. The dashboard refreshes every 10 minutes via a Scheduled Backend Workflow. Product managers and founders can check build health without Travis CI accounts.
Every 10 minutes, call Travis CI API 'Get Repos' for org 'my-company', store results in Bubble BuildStatus records. On dashboard page: Repeating Group Type = BuildStatus, sorted by last_build_at descending, cells showing repo name, status badge (green=passed, red=failed), branch name, last build time
Copy this prompt to try it in Bubble
Per-repository build history drill-down
From the main dashboard, a user clicks a repository row and navigates to a detail page showing the last 25 builds for that repo — commit message, branch, result, build duration, and a link to the Travis CI build log. The data is fetched live on page load with a GET /repo/{slug}/builds call.
On build history page load, call Travis CI API 'Get Builds for Repo' with slug = URL parameter's value, limit = 25; display in repeating group with build number, branch, commit sha (first 7 chars), result badge, duration in seconds formatted as mm:ss
Copy this prompt to try it in Bubble
Travis CI webhook receiver for real-time build notifications
A Bubble Backend Workflow endpoint receives Travis CI webhook POST requests after every build completion. The workflow parses the build payload, updates the corresponding BuildStatus record in Bubble's database, and optionally sends a Slack or email notification if the build failed. This provides real-time updates rather than polling-based refresh.
Backend Workflow 'travis-build-result': receive POST with repository.name, build.state, build.branch, build.commit.message; search Bubble BuildStatus where repo_name = repository.name; update status = build.state, last_build_at = Current date/time; if build.state = 'failed' → trigger Slack notification workflow
Copy this prompt to try it in Bubble
Troubleshooting
Every Travis CI API call returns 403 Forbidden even though the token looks correct
Cause: The Authorization header is using 'Bearer YOUR_TOKEN' format instead of the required 'token YOUR_TOKEN' format. Travis CI API v3 does not accept Bearer-prefixed tokens — this is a known difference from most modern APIs and is a frequent mistake.
Solution: Open API Connector → Travis CI group → shared headers → Authorization header. Verify the value starts with the lowercase word 'token' followed by a single space, then the token string. It must read exactly: 'token abc123...' (not 'Bearer abc123...' and not 'Token abc123...'). Correct the value, save, and re-initialize any calls that previously returned 403.
Bubble's Initialize call detects the wrong field names (e.g., 'build_id' instead of 'id', missing 'state' field) after successful API response
Cause: The Travis-API-Version: 3 shared header is missing or was added at the call level but not the group level. Without this header, Travis CI returns a v2 response shape with different field names and nesting, causing Bubble to detect an incompatible schema.
Solution: Open API Connector → Travis CI group → shared headers. Verify the Travis-API-Version header is present at the API GROUP level (shared headers section), not only on individual calls. The value must be exactly '3'. Delete the existing call, re-add it inside the group, and re-initialize after confirming both shared headers are present at group level.
'There was an issue setting up your call' when initializing the Get Repo Builds call with a slug like 'my-org/my-repo'
Cause: The forward slash in the repository slug ('my-org/my-repo') is being interpreted as a URL path separator by Bubble's API Connector, splitting the URL incorrectly. The resulting endpoint becomes /repo/my-org/my-repo/builds (two path levels) instead of /repo/my-org%2Fmy-repo/builds.
Solution: Either URL-encode the slug by replacing '/' with '%2F' in the dynamic parameter value (pass 'my-org%2Fmy-repo' as the slug parameter), or use the numeric repository ID instead of the slug string. Retrieve the numeric ID from the Get Org Repos call (the 'id' field on each repository object) and store it in your BuildStatus data type. The endpoint /repo/12345678/builds requires no encoding.
Backend Workflow does not run on schedule — Travis CI data in Bubble's database is never updated
Cause: Scheduled Backend Workflows are only available on Bubble Starter plan and above. If the app is on the Free plan, or was downgraded, all scheduled workflows are silently disabled.
Solution: Verify the app is on Starter plan or above via Settings → Plan. If on a paid plan and the workflow is still not running, check Logs → Workflow logs for error messages from the sync workflow. The most common cause of silent failure is the API Connector call returning a 429 rate limit error that Bubble logs but does not surface on the dashboard.
Travis CI webhook posts to the Bubble Backend Workflow URL but Bubble does not update any records
Cause: The Backend Workflow's 'Detect request data' step was not completed with a real Travis CI webhook payload, so Bubble has not detected the incoming JSON structure and cannot map the payload fields to database fields.
Solution: In the Backend Workflow editor, click 'Detect request data.' This activates a listening mode. Trigger a real Travis CI build that sends a webhook. Bubble receives the payload and detects the field names (repository.name, state, branch, etc.). After detection, rewire the workflow actions to use the detected parameter fields. If a real build cannot be triggered immediately, use a tool like webhook.site to capture a sample Travis CI payload, then manually POST it to your Bubble workflow URL in testing mode.
Best practices
- Add BOTH required headers (Authorization and Travis-API-Version: 3) at the API Connector GROUP level — not per call — so every new Travis CI call you add automatically inherits them without manual configuration.
- Use 'include=repo.last_build' in the /owner/{org}/repos request to retrieve build status for all repositories in a single API call rather than making individual /repo/{id}/builds calls per repository — this is dramatically more WU-efficient for dashboards.
- Store numeric Travis CI repository IDs (not slug strings) in Bubble's BuildStatus data type for deduplication and to avoid URL encoding issues with the '/' character in repo slugs.
- Schedule Travis CI data syncs every 5–10 minutes for active development teams rather than fetching live per page load — this prevents repeated API calls per visitor and keeps WU consumption predictable.
- Mark the Authorization header 'Private' in Bubble's API Connector even though Travis CI API tokens are read-only by default — this is a good security habit and prevents accidental token exposure through Bubble's response logging.
- Display a 'Last refreshed' timestamp on your CI dashboard derived from the most recent BuildStatus record's last_build_at field — users need to know whether they are seeing current or cached data.
- Protect any Bubble Backend Workflow webhook endpoint from unauthorized POSTs by adding a secret URL parameter and terminating the workflow if the secret does not match — Travis CI does not sign webhook payloads natively.
- Use the Logs tab → Workflow logs in Bubble to debug failed Travis CI API calls — the response body of a failed Initialize call is displayed there and often contains the specific 403 error message from Travis CI that explains the auth issue.
Alternatives
Jenkins is self-hosted and substantially more complex — it requires exposing a private-network server publicly, fetching a Jenkins-Crumb before every write operation, and handling Basic Auth rather than a simple API token. For teams already using Travis CI's hosted service, the Bubble integration is much simpler. Jenkins is appropriate when self-hosted infrastructure is already in place and more complex pipeline control is needed.
GitLab's REST API and CI/CD pipelines offer richer pipeline data, merge request status, and deployment tracking — all accessible via a personal access token with Bearer auth. If your team uses GitLab rather than GitHub for source control, the GitLab integration may be a better fit than Travis CI for a Bubble CI dashboard.
Docker Hub's REST API shows container image build history and automated build status. For teams that use Docker Hub's automated builds (triggered by GitHub pushes), connecting Bubble to Docker Hub's API can complement or replace a Travis CI integration for monitoring build-and-push pipeline health.
Frequently asked questions
Can I use the travis-ci.org API endpoint instead of travis-ci.com?
No. travis-ci.org was permanently shut down in June 2021. All API calls must target api.travis-ci.com. If you have older documentation, code samples, or tutorials referencing travis-ci.org, they no longer work and will return connection errors or 404 responses.
Why does Travis CI use 'token' instead of 'Bearer' in the Authorization header?
Travis CI's API predates the widespread adoption of the Bearer token standard (RFC 6750). The 'token' prefix is Travis CI's own convention that has remained unchanged for backward compatibility. Both OAuth 2.0 Bearer and Travis's 'token' format are valid HTTP Authorization patterns — they are just different conventions used by different services. Always use 'token YOUR_API_TOKEN' for Travis CI.
Does the Travis CI integration require a paid Bubble plan?
It depends on your use-case. Read-only API calls (displaying build status on page load) work on Bubble's free plan. Scheduled Backend Workflows (polling every 5–10 minutes to keep dashboard data fresh) and inbound webhook receivers (Backend Workflow endpoints) require Bubble Starter plan or above. For a minimal viable CI dashboard that fetches data on each page load without caching, the free plan is sufficient.
What Travis CI build states can Bubble display, and how do I show color-coded badges?
Travis CI v3 returns these build states: 'passed' (green), 'failed' (red), 'errored' (orange — usually a configuration error, not a test failure), 'canceled' (gray), and 'started' (blue — build in progress). In Bubble, add conditional formatting to a Shape or Icon element in your Repeating Group: set background color based on 'Current Cell's BuildStatus's last_build_state = "passed"' → green, and so on for each state value.
Can Bubble receive real-time build notifications from Travis CI instead of polling?
Yes, via Travis CI's webhook notification feature. Configure a Bubble Backend Workflow endpoint as a webhook URL in your .travis.yml file under 'notifications: webhooks: urls.' Travis CI will POST the build result payload to your Bubble workflow URL immediately after each build completes. Backend Workflow endpoints in Bubble require Starter plan or above. Note that Travis CI does not sign webhook payloads, so protect your endpoint with a secret URL parameter.
I use travis-ci.com for open-source projects but my repositories don't appear in the API response. Why?
The /owner/{org}/repos endpoint returns repositories that are synced and enabled for Travis CI builds. A repository that exists on GitHub but has not been activated in Travis CI will not appear. Go to travis-ci.com → your organization → click 'Manage repositories on GitHub' or 'Activate' individual repositories to enable them for CI. After activation, they will appear in the API response.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation