[{"data":1,"prerenderedAt":430},["ShallowReactive",2],{"seite-\u002Fen\u002Fratgeber\u002Fbexio-api-token\u002F":3},{"id":4,"title":5,"body":6,"description":421,"extension":422,"meta":423,"navigation":424,"path":425,"robots":426,"seo":427,"stem":428,"__hash__":429},"seiten_en\u002Fratgeber\u002Fbexio-api-token.md","Create a bexio API token: PAT and Developer Portal",{"type":7,"value":8,"toc":412},"minimark",[9,14,18,23,28,31,43,60,71,75,93,96,122,126,129,174,189,192,196,199,223,243,247,325,329,380,384,387,402,408],[10,11,13],"h1",{"id":12},"create-a-bexio-api-token","Create a bexio API token",[15,16,17],"p",{},"Anyone looking for a “bexio API key” will not find a button for it in bexio itself. Today\nthere are two ways to access the bexio API: a personal access token for your own scripts, or\nan app in the Developer Portal that signs in via OAuth 2. This guide shows both, the first\ncall with the token and the mistakes that usually stop people at the start.",[19,20],"produkt-ablauf",{":schritte":21,"titel":22},"[{\"ort\":\"developer.bexio.com\",\"text\":\"Create a personal token or an app\"},{\"ort\":\"Your script\",\"text\":\"Token in the header “Authorization: Bearer”\",\"eigen\":true},{\"ort\":\"api.bexio.com\",\"text\":\"Contacts, invoices, items as JSON\"}]","Flow: a token is created in the Developer Portal, your script sends it in the header, api.bexio.com returns the data",[24,25,27],"h2",{"id":26},"is-there-a-bexio-api-key","Is there a bexio API key?",[15,29,30],{},"No, not any more. The documentation used to describe fixed “API Tokens” for server-to-server\nconnections. In October 2024 bexio replaced that section with Personal Access Tokens, PAT for\nshort. Older guides that promise a permanent key from the settings are therefore out of date.",[15,32,33,34,38,39,42],{},"Today every request to ",[35,36,37],"code",{},"https:\u002F\u002Fapi.bexio.com"," needs an access token in the header\n",[35,40,41],{},"Authorization: Bearer …",". Where the token comes from depends on who uses the connection:",[44,45,46,54],"ul",{},[47,48,49,53],"li",{},[50,51,52],"strong",{},"Only you",", for example for a script, an export or a test: personal access token (way 1).",[47,55,56,59],{},[50,57,58],{},"An application for others",", for example a plugin on a website or a service for several\ncompanies: an app in the Developer Portal with OAuth 2 (way 2).",[15,61,62,63,70],{},"The reference for all endpoints is at ",[64,65,69],"a",{"href":66,"rel":67},"https:\u002F\u002Fdocs.bexio.com\u002F",[68],"nofollow","docs.bexio.com",". To try things\nout without real accounting data, bexio offers a trial account that you open on bexio.com.",[24,72,74],{"id":73},"way-1-create-a-personal-access-token","Way 1: create a Personal Access Token",[76,77,78,87,90],"ol",{},[47,79,80,81,86],{},"Open ",[64,82,85],{"href":83,"rel":84},"https:\u002F\u002Fdeveloper.bexio.com\u002Fpat",[68],"developer.bexio.com\u002Fpat"," and sign in with your bexio\naccount.",[47,88,89],{},"Create a new token and store it somewhere safe straight away, for example in a password\nmanager or a file only you can read.",[47,91,92],{},"Send the token from your script as a bearer token.",[15,94,95],{},"According to the documentation, a PAT works like this:",[44,97,98,104,110,116],{},[47,99,100,103],{},[50,101,102],{},"Full access:"," a PAT has all default scopes and therefore access to all of the company’s\ndata. Whoever knows it can read invoices and change contacts.",[47,105,106,109],{},[50,107,108],{},"Valid for 60 days:"," after that it has expired and the script needs a new one.",[47,111,112,115],{},[50,113,114],{},"Revoked by deleting it:"," a deleted token can no longer be used. It may take up to one\nhour until the revocation takes full effect.",[47,117,118,121],{},[50,119,120],{},"For personal use only:"," if you want to restrict the rights, for example to reading\ncontacts, use an app instead.",[24,123,125],{"id":124},"test-the-token","Test the token",[15,127,128],{},"The simplest test is a list of contacts:",[130,131,136],"pre",{"className":132,"code":133,"language":134,"meta":135,"style":135},"language-bash shiki shiki-themes github-light github-dark","curl https:\u002F\u002Fapi.bexio.com\u002F2.0\u002Fcontact \\\n  -H 'Accept: application\u002Fjson' \\\n  -H 'Authorization: Bearer \u003Ctoken>'\n","bash","",[35,137,138,155,166],{"__ignoreMap":135},[139,140,143,147,151],"span",{"class":141,"line":142},"line",1,[139,144,146],{"class":145},"sScJk","curl",[139,148,150],{"class":149},"sZZnC"," https:\u002F\u002Fapi.bexio.com\u002F2.0\u002Fcontact",[139,152,154],{"class":153},"sj4cs"," \\\n",[139,156,158,161,164],{"class":141,"line":157},2,[139,159,160],{"class":153},"  -H",[139,162,163],{"class":149}," 'Accept: application\u002Fjson'",[139,165,154],{"class":153},[139,167,169,171],{"class":141,"line":168},3,[139,170,160],{"class":153},[139,172,173],{"class":149}," 'Authorization: Bearer \u003Ctoken>'\n",[15,175,176,177,180,181,184,185,188],{},"If a JSON list comes back, access works. The API reports errors with an HTTP status code and a\nshort JSON body with ",[35,178,179],{},"error_code"," and ",[35,182,183],{},"message",". A call to ",[35,186,187],{},"\u002F3.0\u002Fusers\u002Fme"," also shows which user\nthe token acts as. That matters, because the API never has more rights than this user has in\nbexio.",[15,190,191],{},"The token never belongs in a public Git repository, in JavaScript in the browser or in an\nemail. If it has been exposed anyway: delete it in the Developer Portal and create a new one.",[24,193,195],{"id":194},"way-2-an-app-in-the-developer-portal-with-oauth-2","Way 2: an app in the Developer Portal with OAuth 2",[15,197,198],{},"For anything that other people or companies connect, a PAT is the wrong tool. Then you need an\napp of your own:",[76,200,201,210,213,216],{},[47,202,203,204,209],{},"Sign in to the ",[64,205,208],{"href":206,"rel":207},"https:\u002F\u002Fdeveloper.bexio.com\u002F",[68],"Developer Portal"," and accept the terms of use.\nbexio points in particular to section 4.4 on commercial use.",[47,211,212],{},"Create an app and enter the allowed redirect URLs, the addresses bexio sends the user back\nto after signing in.",[47,214,215],{},"Read the client ID and client secret under “App Details”. The secret stays on the server.",[47,217,218,219,222],{},"Let the user sign in via the “Authorization Code Flow” on ",[35,220,221],{},"auth.bexio.com",". There they see\nwhich rights the app asks for and confirm them.",[15,224,225,226,229,230,233,234,237,238,242],{},"These rights are called scopes, for example ",[35,227,228],{},"contact_show"," for reading contacts or\n",[35,231,232],{},"kb_invoice_edit"," for editing invoices. A write scope includes read access. With the scope\n",[35,235,236],{},"offline_access"," the app also receives a refresh token, which it uses to get new access tokens\nwithout the user signing in again. The guide\n",[64,239,241],{"href":240},"\u002Fen\u002Fratgeber\u002Fbexio-api-wordpress\u002F","connect the bexio API to WordPress"," shows what this looks\nlike in WordPress.",[24,244,246],{"id":245},"which-way-fits","Which way fits?",[248,249,250,266],"table",{},[251,252,253],"thead",{},[254,255,256,260,263],"tr",{},[257,258,259],"th",{},"Question",[257,261,262],{},"Personal Access Token",[257,264,265],{},"App with OAuth 2",[267,268,269,281,292,303,314],"tbody",{},[254,270,271,275,278],{},[272,273,274],"td",{},"Who uses the connection?",[272,276,277],{},"you yourself",[272,279,280],{},"other users or companies",[254,282,283,286,289],{},[272,284,285],{},"Rights",[272,287,288],{},"all of the company’s data",[272,290,291],{},"only the requested scopes",[254,293,294,297,300],{},[272,295,296],{},"Validity",[272,298,299],{},"60 days",[272,301,302],{},"as long as the refresh token is renewed regularly",[254,304,305,308,311],{},[272,306,307],{},"Effort",[272,309,310],{},"a few minutes",[272,312,313],{},"sign-in, token storage, renewal",[254,315,316,319,322],{},[272,317,318],{},"Typical use",[272,320,321],{},"export, test, own script",[272,323,324],{},"plugin, integration, service",[24,326,328],{"id":327},"common-mistakes","Common mistakes",[44,330,331,337,343,349,355,368,374],{},[47,332,333,336],{},[50,334,335],{},"Expired token:"," a script that ran for two months suddenly fails. Usually the PAT has\nexpired after 60 days.",[47,338,339,342],{},[50,340,341],{},"Missing user rights:"," the API works with the rights of the user who created the token or\nconnected the app. If that user has no access to contacts in bexio, the right scope does not\nhelp either.",[47,344,345,348],{},[50,346,347],{},"New scopes on renewal:"," renewing a token keeps the same rights. If the app needs more,\nthe user has to sign in again.",[47,350,351,354],{},[50,352,353],{},"Redirect URL does not match:"," if the address is not entered exactly like this in the app,\nsign-in stops with an error message.",[47,356,357,360,361,180,364,367],{},[50,358,359],{},"Too many requests:"," the API limits requests per minute and company. When the limit is\nreached, it returns status 429; the headers ",[35,362,363],{},"RateLimit-Remaining",[35,365,366],{},"RateLimit-Reset"," tell\nyou how long to wait.",[47,369,370,373],{},[50,371,372],{},"No OpenAPI file:"," according to its own documentation, bexio does not provide an OpenAPI\ndescription. You cannot generate a client automatically but write it from the reference.",[47,375,376,379],{},[50,377,378],{},"Outage rather than error:"," if the API does not respond at all, check the status page\nbexio-status.com before searching your own code.",[24,381,383],{"id":382},"ready-made-solutions","Ready-made solutions",[15,385,386],{},"If you would rather not manage a token yourself, there is a ready-made connection for the most\ncommon cases:",[44,388,389,396],{},[47,390,391,395],{},[64,392,394],{"href":393},"\u002Fen\u002Fbexio-formular-connector\u002F","bexio form connector",": WordPress plugin, enquiries from the\nwebsite form become contacts with a note in bexio. You connect with one click on “Connect to\nbexio”, without an app of your own and without a token someone has to renew every 60 days.",[47,397,398,401],{},[64,399,400],{"href":240},"Connect the bexio API to WordPress",": the way with your\nown app, step by step, if you build it yourself.",[15,403,404],{},[64,405,407],{"href":406},"\u002Fen\u002Fratgeber\u002F","All guides",[409,410,411],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":135,"searchDepth":157,"depth":157,"links":413},[414,415,416,417,418,419,420],{"id":26,"depth":157,"text":27},{"id":73,"depth":157,"text":74},{"id":124,"depth":157,"text":125},{"id":194,"depth":157,"text":195},{"id":245,"depth":157,"text":246},{"id":327,"depth":157,"text":328},{"id":382,"depth":157,"text":383},"Create a bexio API token: why there is no API key any more, Personal Access Token in the Developer Portal, first call with curl, when you need OAuth 2.","md",{},true,"\u002Fratgeber\u002Fbexio-api-token",null,{"title":5,"description":421},"ratgeber\u002Fbexio-api-token","GV3uIH0BygHmBKLs2WdS579CJdgaHS-fgebirVSG1A8",1792037001034]