The api application runs on port 3002. We recommend deploying it to api.{yourdomain}.com.
JTBDOS exports the API from the apps/api directory. It is designed to be run separately from the main app, and is used to run isolate functions that are not part of the main user-facing application e.g. webhooks, cron jobs, etc.
The API is designed to run serverless functions, and is not intended to be used as a traditional Node.js server. However, it is designed to be as flexible as possible, and you can switch to running a traditional server if you need to.Functionally speaking, splitting the API from the main app doesn’t matter if you’re running these projects on Vercel. Serverless functions are all independent pieces of infrastructure and can scale independently. However, having it run independently provides a dedicated endpoint for non-web applications e.g. mobile apps, smart home devices, etc.
Cron jobs: The API is used to run cron jobs. These are defined in the apps/api/app/cron directory. Each cron job is a .ts file that exports a route handler.
Webhooks: The API is used to run inbound webhooks. These are defined in the apps/api/app/webhooks directory. Each webhook is a .ts file that exports a route handler.
{"docsConfig":{"$schema":"https://mintlify.com/docs.json","theme":"mint","name":"jtbdos docs","colors":{"primary":"#f35815","light":"#f35815","dark":"#f35815"},"favicon":"/images/icon.png","styling":{"eyebrows":null,"codeblocks":"system"},"logo":{"light":"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/images/jtbdos-logo-full-with-thrv.svg","dark":"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/images/jtbdos-logo-full-with-thrv.svg"},"background":{"decoration":"windows"},"navbar":{"primary":{"type":"github","href":"https://github.com/thrv/jtbdos4"}},"search":{"prompt":"Search or ask..."},"footer":{"socials":{"x":"https://x.com/haydenbleasel","github":"https://github.com/haydenbleasel/next-forge","linkedin":"https://www.linkedin.com/in/haydenbleasel"}},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"thrv-c7d92728","hasAudioNarration":false,"actualSubdomain":"thrv-c7d92728","customDomains":["docs.jtbdos.com"],"gitSource":{"type":"github","owner":"thrv","repo":"jtbdos4","deployBranch":"main","contentDirectory":"apps/jtbdos-docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6a21e6b403d4026a3ef7729d","collectionId":"e31b713b-bfcb-4d49-8138-d29cda6a8c61","schemaVersion":"v2"},"entitlements":{},"buildId":"6a21e6b403d4026a3ef7729d:success","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"Packages","count":41},{"language":"default","tag":"Migrations","count":15},{"language":"default","tag":"Getting Started","count":10},{"language":"default","tag":"Design System","count":9},{"language":"default","tag":"Addons","count":8},{"language":"default","tag":"Libraries","count":7},{"language":"default","tag":"Apps","count":7},{"language":"default","tag":"Database","count":6},{"language":"default","tag":"Introduction","count":5},{"language":"default","tag":"Security","count":5}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"apps/api","slug":"/apps/api","pageMetadata":{"title":"API","description":"How the \"API\" application works in JTBDOS.","href":"/apps/api"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"How the “API” application works in JTBDOS.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{Heading,Tip}=_components;if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);return _jsxs(_Fragment,{children:[_jsxs(Tip,{children:[`The `,_jsx(_components.code,{children:`api`}),` application runs on port 3002. We recommend deploying it to `,_jsx(_components.code,{children:`api.{yourdomain}.com`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`JTBDOS exports the API from the `,_jsx(_components.code,{children:`apps/api`}),` directory. It is designed to be run separately from the main app, and is used to run isolate functions that are not part of the main user-facing application e.g. webhooks, cron jobs, etc.`]}),`\n`,_jsx(Heading,{level:`2`,id:`overview`,children:`Overview`}),`\n`,_jsx(_components.p,{children:`The API is designed to run serverless functions, and is not intended to be used as a traditional Node.js server. However, it is designed to be as flexible as possible, and you can switch to running a traditional server if you need to.`}),`\n`,_jsx(_components.p,{children:`Functionally speaking, splitting the API from the main app doesn’t matter if you’re running these projects on Vercel. Serverless functions are all independent pieces of infrastructure and can scale independently. However, having it run independently provides a dedicated endpoint for non-web applications e.g. mobile apps, smart home devices, etc.`}),`\n`,_jsx(Heading,{level:`2`,id:`features`,children:`Features`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Cron jobs`}),`: The API is used to run `,_jsx(_components.a,{href:`/packages/cron`,children:`cron jobs`}),`. These are defined in the `,_jsx(_components.code,{children:`apps/api/app/cron`}),` directory. Each cron job is a `,_jsx(_components.code,{children:`.ts`}),` file that exports a route handler.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Webhooks`}),`: The API is used to run `,_jsx(_components.a,{href:`/packages/webhooks`,children:`inbound webhooks`}),`. These are defined in the `,_jsx(_components.code,{children:`apps/api/app/webhooks`}),` directory. Each webhook is a `,_jsx(_components.code,{children:`.ts`}),` file that exports a route handler.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"API","description":"How the \"API\" application works in JTBDOS.","href":"/apps/api"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Overview","slug":"overview","depth":2,"children":[]},{"title":"Features","slug":"features","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"thrv-c7d92728","siteName":"jtbdos docs","title":"API - jtbdos docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"originalFileLocation":"apps/api.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"How the \u0026quot;API\u0026quot; application works in JTBDOS.\">\u003cmeta data-mint-head name=\"application-name\" content=\"jtbdos docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"API - jtbdos docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"How the \u0026quot;API\u0026quot; application works in JTBDOS.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"jtbdos docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.jtbdos.com/apps/api\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://thrv-c7d92728.mintlify.app/_mintlify/api/og/v2?division=Documentation\u0026amp;title=API\u0026amp;description=How+the+%22API%22+application+works+in+JTBDOS.\u0026amp;theme=87e5d5443d5dde3c753ee24e\u0026amp;signature=72e4170a8d63355d3bac3a4d91a54917a0b7c71a7a9876d3a28bbac55c38ce12\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"API - jtbdos docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"How the \u0026quot;API\u0026quot; application works in JTBDOS.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://thrv-c7d92728.mintlify.app/_mintlify/api/og/v2?division=Documentation\u0026amp;title=API\u0026amp;description=How+the+%22API%22+application+works+in+JTBDOS.\u0026amp;theme=87e5d5443d5dde3c753ee24e\u0026amp;signature=72e4170a8d63355d3bac3a4d91a54917a0b7c71a7a9876d3a28bbac55c38ce12\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"jtbdos docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#f35815\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.jtbdos.com/apps/api\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/apps/api.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.jtbdos.com/#organization\",\"name\":\"jtbdos docs\",\"url\":\"https://docs.jtbdos.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintlify.s3.us-west-1.amazonaws.com/thrv-c7d92728/images/jtbdos-logo-full-with-thrv.svg\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.jtbdos.com#website\",\"name\":\"jtbdos docs\",\"url\":\"https://docs.jtbdos.com\",\"publisher\":{\"@id\":\"https://docs.jtbdos.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.jtbdos.com/apps/api#webpage\",\"url\":\"https://docs.jtbdos.com/apps/api\",\"name\":\"API\",\"description\":\"How the \\\"API\\\" application works in JTBDOS.\",\"isPartOf\":{\"@id\":\"https://docs.jtbdos.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.jtbdos.com/apps/api#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.jtbdos.com/apps/api#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"jtbdos docs\",\"item\":\"https://docs.jtbdos.com\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"API\",\"item\":\"https://docs.jtbdos.com/apps/api\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.jtbdos.com/apps/api#article\",\"headline\":\"API\",\"name\":\"API\",\"description\":\"How the \\\"API\\\" application works in JTBDOS.\",\"url\":\"https://docs.jtbdos.com/apps/api\",\"mainEntityOfPage\":{\"@id\":\"https://docs.jtbdos.com/apps/api#webpage\"},\"publisher\":{\"@id\":\"https://docs.jtbdos.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.jtbdos.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"jtbdos docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"jtbdos docs","nav":{"global":null,"tabs":[{"tab":"Getting Started","pages":[{"title":"Getting Started","href":"/overview"}]},{"tab":"Apps","groups":[{"group":"","pages":[{"title":"API","href":"/apps/api"},{"title":"App","description":"How the main application works in JTBDOS.","href":"/apps/app"},{"title":"Documentation","href":"/apps/docs"},{"title":"Email","href":"/apps/email"},{"title":"Storybook","href":"/apps/storybook"},{"title":"Studio","href":"/apps/studio"},{"title":"Web","href":"/apps/web"}]}]},{"tab":"Packages","pages":[{"title":"Packages","href":"/packages/ai"}]},{"tab":"Recipes","pages":[{"title":"Recipes","href":"/recipes/ai-chatbot"}]},{"tab":"Migrations","pages":[{"title":"Migrations","href":"/migrations/authentication/authjs"}]},{"tab":"Addons","pages":[{"title":"Addons","href":"/addons/friendlier-words"}]}]},"basePath":"","title":"API - jtbdos docs","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":[],"chunks":[]}