[{"data":1,"prerenderedAt":1728},["ShallowReactive",2],{"blog-api-credentials-vs-oauth-2-0":3,"blog-related-api-credentials-vs-oauth-2-0":595},{"id":4,"title":5,"author":6,"body":7,"category":568,"coverImage":569,"createdAt":571,"description":13,"extension":572,"featured":573,"meta":574,"navigation":576,"path":577,"publishedAt":571,"seo":578,"slug":581,"status":582,"stem":583,"subtitle":584,"tags":585,"updatedAt":571,"__hash__":594},"blog/blog/2026/06/11-api-credentials-vs-oauth-2-0.md","API Credentials vs OAuth 2.0 in NewLedger","newledger-team",{"type":8,"value":9,"toc":554},"minimark",[10,14,36,43,46,51,109,113,120,134,137,151,154,168,172,178,181,183,203,205,216,224,230,234,237,242,252,260,263,267,270,292,296,302,305,316,322,330,334,404,407,421,428,433,437,473,477,480,505,512,517,520,524,545],[11,12,13],"p",{},"If you are integrating with NewLedger, the first architecture decision is simple:",[15,16,17,30],"ul",{},[18,19,20,24,25,29],"li",{},[21,22,23],"strong",{},"Use API credentials"," when your server is the thing connecting and you can store a ",[26,27,28],"code",{},"client_secret"," safely.",[18,31,32,35],{},[21,33,34],{},"Use OAuth 2.0"," when a user needs to approve access in the browser and the client should receive delegated access instead of your stored secret.",[11,37,38,39,42],{},"The confusion usually comes from the fact that both live under ",[21,40,41],{},"App Connect",", both issue scoped bearer tokens, and both can power serious production workflows. The difference is the trust model.",[11,44,45],{},"In a finance system, that trust model matters. The authentication pattern you choose determines whether secrets stay on your backend, whether a user must approve the connection explicitly, and whether audit and revocation remain straightforward when something changes.",[47,48,50],"h2",{"id":49},"the-short-answer","The short answer",[52,53,54,67],"table",{},[55,56,57],"thead",{},[58,59,60,64],"tr",{},[61,62,63],"th",{},"If your integration looks like this...",[61,65,66],{},"Use this",[68,69,70,81,91,100],"tbody",{},[58,71,72,76],{},[73,74,75],"td",{},"A backend job, ETL worker, partner sync, internal ops tool, or server-side automation you control",[73,77,78],{},[21,79,80],{},"API credentials",[58,82,83,86],{},[73,84,85],{},"A browser-based app, partner product, or AI client that needs the user to sign in and approve scope",[73,87,88],{},[21,89,90],{},"OAuth 2.0",[58,92,93,96],{},[73,94,95],{},"A ChatGPT or MCP-style connection using your company MCP URL",[73,97,98],{},[21,99,90],{},[58,101,102,105],{},[73,103,104],{},"A daemon or cron job with no interactive user at connect time",[73,106,107],{},[21,108,80],{},[47,110,112],{"id":111},"what-api-credentials-are-for","What API credentials are for",[11,114,115,116,119],{},"API credentials are the ",[21,117,118],{},"server-to-server"," path.",[11,121,122,123,126,127,130,131,133],{},"You create an app under ",[21,124,125],{},"Settings → App Connect → API Credentials",", delegate the permissions it needs, copy the ",[26,128,129],{},"client_id"," and ",[26,132,28],{},", and exchange them for short-lived bearer tokens from your backend.",[11,135,136],{},"This is usually the right choice when:",[15,138,139,142,145,148],{},[18,140,141],{},"You control the integration runtime",[18,143,144],{},"You have a secrets manager or vault",[18,146,147],{},"You do not need a browser redirect or consent screen",[18,149,150],{},"The integration should keep running without a person re-approving each sync",[11,152,153],{},"Typical examples:",[15,155,156,159,162,165],{},[18,157,158],{},"Nightly revenue sync into a warehouse",[18,160,161],{},"Internal invoice-drafting automation",[18,163,164],{},"ERP, CRM, payroll, or payments reconciliation jobs",[18,166,167],{},"Partner backends that call NewLedger on behalf of a tenant under a pre-arranged setup",[47,169,171],{"id":170},"what-oauth-20-is-for","What OAuth 2.0 is for",[11,173,174,175,119],{},"OAuth 2.0 is the ",[21,176,177],{},"delegated-access",[11,179,180],{},"Instead of handing a client your stored secret, you send the user through NewLedger's sign-in and consent flow. The user chooses the company, reviews the requested permissions, confirms with 2FA, and then the client receives access within that approved scope.",[11,182,136],{},[15,184,185,188,191,194,197],{},[18,186,187],{},"The client is user-facing",[18,189,190],{},"The connection starts from another product or browser flow",[18,192,193],{},"You need a redirect URI",[18,195,196],{},"The app should only work after explicit user consent",[18,198,199,200],{},"The client is public and should use ",[21,201,202],{},"PKCE",[11,204,153],{},[15,206,207,210,213],{},[18,208,209],{},"ChatGPT or another MCP-capable AI client",[18,211,212],{},"A custom partner portal that lets the user connect their NewLedger workspace",[18,214,215],{},"A public integration that cannot safely hold a shared long-lived secret on-device",[11,217,218],{},[219,220],"img",{"alt":221,"src":222,"title":223},"NewLedger App Connect OAuth 2.0 approval screen","https://storage.googleapis.com/nl-blog/features/setting/app-connect-oauth-2.0.webp","App Connect OAuth 2.0 approval screen",[11,225,226],{},[227,228,229],"em",{},"OAuth 2.0 is the right path when the user needs to see the app, review scope, and approve access explicitly.",[47,231,233],{"id":232},"the-decision-rule-we-recommend","The decision rule we recommend",[11,235,236],{},"Ask one question:",[11,238,239],{},[21,240,241],{},"\"Does this connection need a person to approve access in the browser?\"",[11,243,244,245,248,249,251],{},"If ",[21,246,247],{},"no",", start with ",[21,250,80],{},".",[11,253,244,254,257,258,251],{},[21,255,256],{},"yes",", use ",[21,259,90],{},[11,261,262],{},"That rule is more reliable than asking whether the integration is \"advanced,\" \"AI-powered,\" or \"third-party.\" Plenty of sophisticated integrations should still use API credentials. Plenty of lightweight ones need OAuth because the user must approve them directly.",[47,264,266],{"id":265},"why-security-teams-care-about-this-split","Why security teams care about this split",[11,268,269],{},"This is not security theater. The distinction changes real control boundaries:",[15,271,272,277,282,289],{},[18,273,274,276],{},[21,275,80],{}," keep shared secrets on infrastructure you operate and keep the browser out of the token exchange path.",[18,278,279,281],{},[21,280,90],{}," makes the approval visible to the user, which is critical when the client is third-party, user-facing, or initiated outside your own backend.",[18,283,284,285,288],{},"Both let you apply ",[21,286,287],{},"least privilege",", but they do it at different moments: delegated at app creation for API credentials, reviewed at consent time for OAuth.",[18,290,291],{},"Both are easier to govern when finance keeps a named owner, a documented purpose, and a clear revocation path for every connection.",[47,293,295],{"id":294},"how-this-maps-to-mcp-and-chatgpt","How this maps to MCP and ChatGPT",[11,297,298,299,251],{},"MCP is not a separate auth model. It is one of the clients that uses NewLedger's ",[21,300,301],{},"OAuth 2.0 consent flow",[11,303,304],{},"So if the use case is:",[15,306,307,310,313],{},[18,308,309],{},"\"Connect ChatGPT to our books\"",[18,311,312],{},"\"Paste the company MCP URL into an AI client\"",[18,314,315],{},"\"Approve scopes and let the assistant read reports or draft entries\"",[11,317,318,319,321],{},"then the right answer is ",[21,320,90],{},", not API credentials.",[11,323,324,325,251],{},"For the full walkthrough, see ",[326,327,329],"a",{"href":328},"/blog/mcp-for-accounting","MCP for accounting",[47,331,333],{"id":332},"security-differences-that-matter","Security differences that matter",[52,335,336,347],{},[55,337,338],{},[58,339,340,343,345],{},[61,341,342],{},"Topic",[61,344,80],{},[61,346,90],{},[68,348,349,362,373,382,393],{},[58,350,351,354,359],{},[73,352,353],{},"Secret storage",[73,355,356,357],{},"Your backend stores the ",[26,358,28],{},[73,360,361],{},"Public clients use PKCE and do not rely on a shared long-lived secret",[58,363,364,367,370],{},[73,365,366],{},"Browser consent",[73,368,369],{},"No",[73,371,372],{},"Yes",[58,374,375,378,380],{},[73,376,377],{},"Redirect URI",[73,379,369],{},[73,381,372],{},[58,383,384,387,390],{},[73,385,386],{},"Best fit",[73,388,389],{},"System-to-system automation",[73,391,392],{},"Delegated user-approved access",[58,394,395,398,401],{},[73,396,397],{},"Revocation path",[73,399,400],{},"Revoke or rotate the app credential",[73,402,403],{},"Delete the OAuth connection or revoke the client",[11,405,406],{},"Both approaches still use:",[15,408,409,412,415,418],{},[18,410,411],{},"Scoped permissions",[18,413,414],{},"App Connect visibility",[18,416,417],{},"Audit history",[18,419,420],{},"Short-lived access tokens",[11,422,423],{},[219,424],{"alt":425,"src":426,"title":427},"NewLedger App Connect OAuth 2.0 connections detail","https://storage.googleapis.com/nl-blog/features/setting/app-connect-oauth-2.0-detail.webp","App Connect OAuth 2.0 connection details",[11,429,430],{},[227,431,432],{},"The OAuth 2.0 connection surface should stay reviewable after setup, not disappear into implementation detail.",[47,434,436],{"id":435},"a-secure-rollout-checklist","A secure rollout checklist",[438,439,440,447,454,464,470],"ol",{},[18,441,442,443,446],{},"Use a ",[21,444,445],{},"test company or non-production workspace"," before issuing live access.",[18,448,449,450,453],{},"Start with the ",[21,451,452],{},"minimum scopes"," needed for the first working version.",[18,455,456,457,459,460,463],{},"Keep ",[26,458,28],{}," values in a ",[21,461,462],{},"vault or secrets manager",", never in frontend code, local config committed to git, or chat threads.",[18,465,466,467,251],{},"Give each integration a clear ",[21,468,469],{},"owner, business purpose, and review cadence",[18,471,472],{},"Make revocation easy to execute by documenting whether the team should rotate an API credential or delete an OAuth connection.",[47,474,476],{"id":475},"what-to-publish-on-your-own-integration-pages","What to publish on your own integration pages",[11,478,479],{},"If you are writing docs, onboarding notes, or partner setup steps:",[15,481,482,488,493,499,502],{},[18,483,484,485,487],{},"Say ",[21,486,80],{}," when the reader is creating a server-side integration.",[18,489,484,490,492],{},[21,491,90],{}," when the reader is authorizing a client through the browser.",[18,494,456,495,498],{},[21,496,497],{},"OAuth 2.1"," guidance on its own technical page if you need to document stricter implementation profiles or migration rules.",[18,500,501],{},"Avoid using \"OAuth\" as a catch-all for every API integration.",[18,503,504],{},"Avoid telling readers to create API credentials if the real flow is redirect-based consent.",[11,506,507],{},[219,508],{"alt":509,"src":510,"title":511},"NewLedger App Connect OAuth 2.0 registration screen","https://storage.googleapis.com/nl-blog/features/setting/app-connect-oauth-2.0-register.webp","App Connect OAuth 2.0 registration screen",[11,513,514],{},[227,515,516],{},"Registration belongs to the delegated-access path. It should not be mixed into API credential onboarding.",[11,518,519],{},"That language distinction saves a lot of setup friction.",[47,521,523],{"id":522},"where-to-go-next","Where to go next",[15,525,526,533,538],{},[18,527,528,529],{},"Need the full server-side walkthrough: ",[326,530,532],{"href":531},"/blog/accounting-api-integration","The Architecture of Modern Finance: Scaling Operations via Accounting APIs",[18,534,535,536],{},"Need the AI-client path: ",[326,537,329],{"href":328},[18,539,540,541],{},"Need endpoint details: ",[326,542,544],{"href":543},"/api-documentation","NewLedger API documentation",[11,546,547,548,550,551,553],{},"In practice, most teams should treat ",[21,549,80],{}," as the default integration path and ",[21,552,90],{}," as the delegated-access path. Once you frame it that way, the App Connect model becomes much easier to explain and much harder to misuse.",{"title":555,"searchDepth":556,"depth":556,"links":557},"",2,[558,559,560,561,562,563,564,565,566,567],{"id":49,"depth":556,"text":50},{"id":111,"depth":556,"text":112},{"id":170,"depth":556,"text":171},{"id":232,"depth":556,"text":233},{"id":265,"depth":556,"text":266},{"id":294,"depth":556,"text":295},{"id":332,"depth":556,"text":333},{"id":435,"depth":556,"text":436},{"id":475,"depth":556,"text":476},{"id":522,"depth":556,"text":523},"guides",{"src":222,"alt":221,"credit":570},"NewLedger Editorial","2026-06-11","md",false,{"contributors":575},[6],true,"/blog/2026/06/11-api-credentials-vs-oauth-2-0",{"title":579,"description":580,"image":222},"API credentials vs OAuth 2.0 | NewLedger","Choose the right App Connect flow in NewLedger: API credentials for server-side integrations, OAuth 2.0 for delegated user-approved access and MCP clients.","api-credentials-vs-oauth-2-0","published","blog/2026/06/11-api-credentials-vs-oauth-2-0","Which App Connect path should you use for server-side integrations, partner apps, and MCP clients like ChatGPT?",[586,587,588,589,590,591,592,593],"api","oauth","oauth2","app-connect","integrations","mcp","automation","newledger","PXocR0eTBXVMaDyXOqyuzsc4En5KO8oWx7sLKJExZMk",[596],{"id":597,"title":532,"author":6,"body":598,"category":568,"coverImage":1708,"createdAt":1710,"description":602,"extension":572,"featured":573,"meta":1711,"navigation":576,"path":1713,"publishedAt":1710,"seo":1714,"slug":1717,"status":582,"stem":1718,"subtitle":1719,"tags":1720,"updatedAt":571,"__hash__":1727},"blog/blog/2026/05/26-accounting-api-integration.md",{"type":8,"value":599,"toc":1682},[600,603,609,632,638,642,645,702,713,720,777,783,787,795,800,830,834,868,875,880,887,892,899,904,908,915,921,925,933,944,948,975,979,982,986,989,1004,1007,1014,1018,1021,1025,1032,1051,1058,1062,1067,1071,1074,1078,1085,1099,1102,1108,1113,1117,1120,1164,1173,1179,1184,1188,1199,1202,1234,1245,1248,1252,1313,1317,1404,1414,1418,1422,1453,1458,1490,1494,1523,1527,1531,1569,1573,1621,1628,1630,1673],[11,601,602],{},"If you run a small or mid-size business, “modernizing operations” usually means the same few moves: less re-keying between tools, faster answers from your numbers, and software that talks to each other instead of living in separate tabs.",[11,604,605,608],{},[21,606,607],{},"Accounting API integration"," is what makes that possible — your accounting system exposes a controlled way for other apps to read (and, where you allow it, draft) financial data. You stay in charge of what connects, what it can do, and when access ends.",[11,610,611,612,614,615,617,618,621,622,624,625,631],{},"On NewLedger, that layer is ",[21,613,41],{},". For most accounting API integration work — automations, internal tools, partner sync — you use ",[21,616,80],{}," (client ID + secret, server-side token exchange). When an external client needs a ",[21,619,620],{},"delegated, browser-based approval flow",", you use ",[21,623,90],{}," with consent, redirect URIs, and PKCE where required. ",[326,626,630],{"href":627,"rel":628},"https://modelcontextprotocol.io",[629],"nofollow","MCP"," clients such as ChatGPT are one example of that delegated flow. This guide covers both, in that order.",[11,633,634,635,251],{},"In finance, that choice is not just technical. It decides ",[21,636,637],{},"where secrets live, how narrowly access can be scoped, whether a human must approve the connection, and how cleanly your team can revoke access later",[47,639,641],{"id":640},"why-accounting-api-integration-helps-when-you-modernize-ops","Why accounting API integration helps when you modernize ops",[11,643,644],{},"Typical SMB goals and how a connected accounting API supports them:",[52,646,647,657],{},[55,648,649],{},[58,650,651,654],{},[61,652,653],{},"What you're trying to do",[61,655,656],{},"How integration helps",[68,658,659,669,680,694],{},[58,660,661,664],{},[73,662,663],{},"Ask questions about cash, AR, or expenses without exporting spreadsheets",[73,665,666,667],{},"MCP clients (e.g. ChatGPT) read live data after you approve OAuth 2.0 consent — see ",[326,668,329],{"href":328},[58,670,671,674],{},[73,672,673],{},"Automate repetitive work (invoice drafts, expense capture, categorization hints)",[73,675,676,677,679],{},"Automations use ",[21,678,80],{}," and call the API instead of copying numbers by hand",[58,681,682,685],{},[73,683,684],{},"Connect a stack you already use (payments, CRM, industry tools)",[73,686,687,688,690,691,693],{},"Partner apps sync through ",[21,689,80],{}," or ",[21,692,90],{},", depending on whether they need server-side credentials or user-approved delegated access",[58,695,696,699],{},[73,697,698],{},"Keep control as you add tools",[73,700,701],{},"One place to see what's connected, revoke access, and review activity",[11,703,704,705,708,709,712],{},"The point is not “open the ledger to the internet.” It's ",[21,706,707],{},"replace manual bridges"," — email attachments, CSV exports, staff pasting totals into chat — with ",[21,710,711],{},"governed connections"," you can audit and turn off.",[11,714,715,716,719],{},"App Connect issues ",[21,717,718],{},"scoped, auditable access"," — never your login password. Two connection styles exist; they are not interchangeable:",[52,721,722,735],{},[55,723,724],{},[58,725,726,729,732],{},[61,727,728],{},"Connection style",[61,730,731],{},"Use for",[61,733,734],{},"How it works",[68,736,737,762],{},[58,738,739,743,746],{},[73,740,741],{},[21,742,80],{},[73,744,745],{},"Accounting API integration — automations, scripts, partner backends, anything you host",[73,747,748,749,752,753,755,756,758,759],{},"Create an app in ",[21,750,751],{},"Settings → App Connect",", delegate permissions, exchange ",[26,754,129],{}," + ",[26,757,28],{}," for bearer tokens. ",[21,760,761],{},"No redirect URI, no consent screen.",[58,763,764,768,771],{},[73,765,766],{},[21,767,90],{},[73,769,770],{},"MCP clients, partner apps, or custom clients that need a user-approved connection",[73,772,773,774,251],{},"Register or use an OAuth client, send the user through NewLedger's consent flow, and complete the token exchange with redirect URI + PKCE where required. Managed under ",[21,775,776],{},"OAuth Connections",[11,778,779,782],{},[21,780,781],{},"If you are modernizing ops with integrations and automations, start with API credentials below."," OAuth 2.0 is documented later for delegated client connections, with MCP as the most common example.",[47,784,786],{"id":785},"set-up-accounting-api-integration-api-credentials","Set up accounting API integration (API credentials)",[11,788,789,791,792,794],{},[21,790,23],{}," when you control the server, can store a ",[26,793,28],{}," safely, and do not need an interactive consent screen. This is the default path for SMB accounting API integration.",[796,797,799],"h3",{"id":798},"what-you-get","What you get",[15,801,802,807,812,818,824],{},[18,803,804,806],{},[21,805,411],{}," — each app only receives permissions you delegate at create time (and your user account must already hold them).",[18,808,809,811],{},[21,810,420],{}," — clients request a new token from the token endpoint when one expires.",[18,813,814,817],{},[21,815,816],{},"One-time secrets"," — the client secret is shown only at create or rotate.",[18,819,820,823],{},[21,821,822],{},"Lifecycle control"," — revoke, delete, or restore apps from App Connect; activity is logged.",[18,825,826,829],{},[21,827,828],{},"No OAuth redirect"," — setup is entirely in App Connect settings plus server-side token exchange.",[796,831,833],{"id":832},"steps-in-the-workspace","Steps in the workspace",[438,835,836,846,855,865],{},[18,837,838,839,841,842,845],{},"Open ",[21,840,751],{}," and use the ",[21,843,844],{},"API Credentials"," tab to see connected apps, permissions, and last-used dates.",[18,847,848,851,852,854],{},[21,849,850],{},"Create App",", choose ",[21,853,80],{},", name the integration, and pick the permissions it may use.",[18,856,857,858,130,861,864],{},"Copy the ",[21,859,860],{},"client ID",[21,862,863],{},"client secret"," once (the secret is only shown at create or rotate).",[18,866,867],{},"Open the app detail anytime to review scope, rotate the secret, or revoke access.",[11,869,870],{},[219,871],{"alt":872,"src":873,"title":874},"App Connect API credentials list in NewLedger settings","https://storage.googleapis.com/nl-blog/features/setting/api-credential-list.webp","App Connect API credentials list",[11,876,877],{},[227,878,879],{},"The API Credentials tab lists each connected app, its delegated permissions, and when it was last used.",[11,881,882],{},[219,883],{"alt":884,"src":885,"title":886},"Create an API credential app with scoped permissions","https://storage.googleapis.com/nl-blog/features/setting/api-credential-form.webp","API credential create form",[11,888,889],{},[227,890,891],{},"When you create an app, you name it, set optional expiry, and delegate only the permissions that automation needs.",[11,893,894],{},[219,895],{"alt":896,"src":897,"title":898},"API credential detail with client ID and lifecycle actions","https://storage.googleapis.com/nl-blog/features/setting/api-credential-detail.webp","API credential detail view",[11,900,901],{},[227,902,903],{},"The detail view is where you audit scope, rotate secrets, or revoke the app.",[796,905,907],{"id":906},"token-exchange-server-side","Token exchange (server-side)",[11,909,910,911,914],{},"Your integration exchanges the client ID and secret for a ",[21,912,913],{},"short-lived bearer token"," using the App Connect token API. There is no browser step, no redirect URI, and no PKCE.",[11,916,917,918,920],{},"Use the ",[326,919,544],{"href":543}," for request formats, scopes, and company-scoped token exchange. Store secrets in a vault or secrets manager — never in source control, client-side code, or chat.",[47,922,924],{"id":923},"oauth-20-setup-for-delegated-clients-eg-chatgpt-mcp","OAuth 2.0 setup for delegated clients (e.g. ChatGPT / MCP)",[11,926,927,930,931,251],{},[21,928,929],{},"OAuth 2.0 authorization code + PKCE is the delegated-access path"," — not the flow used by API credential apps under the API Credentials tab. When you add your company MCP URL in ChatGPT (or another supported client), that product drives the OAuth flow below. The same consent model also supports other custom or partner clients that need user-approved access instead of a stored ",[26,932,28],{},[11,934,935,936,938,939,943],{},"For product context and what to ask your AI assistant, see ",[326,937,329],{"href":328},". For a concise decision guide, see ",[326,940,942],{"href":941},"/blog/api-credentials-vs-oauth-2-0","API credentials vs OAuth 2.0 in NewLedger",". This section covers the OAuth mechanics behind delegated connections.",[796,945,947],{"id":946},"what-you-get-with-oauth-20","What you get with OAuth 2.0",[15,949,950,956,961,967],{},[18,951,952,955],{},[21,953,954],{},"Consent-first access"," — pick a company, review permissions, confirm with 2FA before any token is issued.",[18,957,958,960],{},[21,959,411],{}," — same permission strings as API credentials, but chosen on the consent screen.",[18,962,963,966],{},[21,964,965],{},"PKCE (S256 only)"," — required for public MCP clients.",[18,968,969,972,973,251],{},[21,970,971],{},"Refresh tokens"," — rotate on use; revoke by deleting the connection under ",[21,974,776],{},[796,976,978],{"id":977},"end-user-flow-connect-a-delegated-client","End-user flow: connect a delegated client",[11,980,981],{},"Use the in-app setup guides; you do not need to call the API yourself to connect ChatGPT.",[796,983,985],{"id":984},"_1-copy-your-company-mcp-url","1. Copy your company MCP URL",[11,987,988],{},"In your NewLedger workspace:",[438,990,991,995,1001],{},[18,992,838,993],{},[21,994,751],{},[18,996,997,998],{},"Click ",[21,999,1000],{},"MCP Server",[18,1002,1003],{},"Copy the company-specific MCP endpoint",[11,1005,1006],{},"That URL is unique to the company you have selected. Use it when the external client asks for a server address.",[11,1008,1009,1010,1013],{},"You can also reach per-client instructions from ",[21,1011,1012],{},"Settings → Integrations"," (for example the ChatGPT setup page).",[796,1015,1017],{"id":1016},"_2-start-connection-in-the-external-app","2. Start connection in the external app",[11,1019,1020],{},"In ChatGPT (or another supported MCP client), add a connector and paste your MCP URL. For other OAuth-capable clients, start the connection from the client using the redirect URI and client registration it expects. The client opens NewLedger's sign-in and consent flow in your browser.",[796,1022,1024],{"id":1023},"_3-review-and-approve-on-the-consent-screen","3. Review and approve on the consent screen",[11,1026,1027,1028,1031],{},"You land on NewLedger's ",[21,1029,1030],{},"OAuth consent"," page. The screen shows:",[15,1033,1034,1037,1044],{},[18,1035,1036],{},"Which app is requesting access (name, domain, logo when provided)",[18,1038,1039,1040,1043],{},"Which ",[21,1041,1042],{},"company"," the connection applies to (you can switch companies if you have access to more than one)",[18,1045,1046,1047,1050],{},"The ",[21,1048,1049],{},"permission list"," that will become the token scope — you can remove individual permissions before approving",[11,1052,1053,1054,1057],{},"When you continue, NewLedger asks for a ",[21,1055,1056],{},"verification code"," (TOTP or another configured confirmation method). Authorization does not complete without it.",[11,1059,1060],{},[219,1061],{"alt":221,"src":222,"title":223},[11,1063,1064],{},[227,1065,1066],{},"This screen is part of App Connect's OAuth 2.0 flow. API credential apps are configured entirely under the API Credentials tab and do not use browser consent.",[796,1068,1070],{"id":1069},"_4-return-to-the-client","4. Return to the client",[11,1072,1073],{},"After approval, you are returned to the MCP client. It completes the connection securely on its side, then can call your company's MCP server within the permissions you approved.",[796,1075,1077],{"id":1076},"_5-manage-connections-later","5. Manage connections later",[11,1079,1080,1081,1084],{},"Approved OAuth apps appear under ",[21,1082,1083],{},"Settings → App Connect → OAuth Connections",". From there you can:",[15,1086,1087,1090,1093],{},[18,1088,1089],{},"See when the connection was consented",[18,1091,1092],{},"Open connection details (scopes, MCP URL, client metadata)",[18,1094,1095,1098],{},[21,1096,1097],{},"Delete"," the connection — this revokes refresh tokens and blocks active access; the external app must ask for consent again",[11,1100,1101],{},"Idle connections are surfaced in the list so you can audit what still has access.",[11,1103,1104],{},[219,1105],{"alt":1106,"src":426,"title":1107},"NewLedger App Connect OAuth 2.0 connections list","App Connect OAuth 2.0 connections list",[11,1109,1110],{},[227,1111,1112],{},"OAuth 2.0 connections stay visible in App Connect so finance and security teams can review scopes, usage context, and revocation options later.",[796,1114,1116],{"id":1115},"register-a-custom-oauth-app","Register a custom OAuth app",[11,1118,1119],{},"Some delegated setups need you to register an OAuth client in NewLedger instead of relying on the external product's built-in registration. That includes MCP development, partner app testing, and any browser-based client connection you operate yourself.",[438,1121,1122,1127,1134,1154],{},[18,1123,1124,1125],{},"Go to ",[21,1126,751],{},[18,1128,1129,1130,1133],{},"Choose ",[21,1131,1132],{},"Register OAuth App"," (or create a new app and pick the OAuth connection type)",[18,1135,1136,1137],{},"Fill in:\n",[15,1138,1139,1145],{},[18,1140,1141,1144],{},[21,1142,1143],{},"App name"," — shown on the consent screen",[18,1146,1147,1149,1150,1153],{},[21,1148,377],{}," — must match ",[21,1151,1152],{},"exactly"," what the MCP client shows (HTTPS required)",[18,1155,1156,1157,1159,1160,1163],{},"Save the ",[21,1158,860],{},". Public clients use PKCE and do ",[21,1161,1162],{},"not"," receive a long-lived client secret.",[1165,1166,1167],"blockquote",{},[11,1168,1169,1172],{},[21,1170,1171],{},"ChatGPT tip:"," Copy the redirect URI from ChatGPT's connector setup. Do not guess or reuse URIs from other products.",[11,1174,1175],{},[219,1176],{"alt":1177,"src":510,"title":1178},"NewLedger App Connect OAuth 2.0 app registration screen","App Connect OAuth 2.0 app registration",[11,1180,1181],{},[227,1182,1183],{},"Register OAuth 2.0 clients only when the integration genuinely needs delegated browser-based access. Keep server-side automations on API credentials instead.",[796,1185,1187],{"id":1186},"building-against-newledgers-oauth-layer","Building against NewLedger's OAuth layer",[11,1189,1190,1191,1194,1195,1198],{},"App Connect OAuth is implemented on the ",[21,1192,1193],{},"NewLedger API"," and completed in the ",[21,1196,1197],{},"NewLedger web app"," consent UI. API credential apps do not use that flow.",[11,1200,1201],{},"If you are building or certifying an integration (not just connecting ChatGPT as a user):",[15,1203,1204,1211,1218,1228],{},[18,1205,1206,1207,1210],{},"Follow the ",[21,1208,1209],{},"OAuth 2.0 authorization code flow with PKCE (S256)"," used by App Connect for delegated access.",[18,1212,1213,1214,1217],{},"Use ",[21,1215,1216],{},"OAuth discovery"," metadata published by NewLedger for your environment rather than hard-coding URLs.",[18,1219,1220,1221,130,1224,1227],{},"Complete approval only through the ",[21,1222,1223],{},"signed-in consent screen",[21,1225,1226],{},"2FA"," — tokens must not be issued without an explicit user action in the app.",[18,1229,1230,1231,1233],{},"Document integration details in your own runbook; use the ",[326,1232,544],{"href":543}," for supported App Connect and MCP operations.",[11,1235,1236,1237,1240,1241,1244],{},"If you want to document an ",[21,1238,1239],{},"OAuth 2.1-specific profile or migration path",", keep that as a separate technical page or implementation note. This guide is intentionally about the ",[21,1242,1243],{},"OAuth 2.0 product flow"," users see in App Connect.",[11,1246,1247],{},"We do not publish step-by-step token or authorize API recipes in this post. That reduces noise for readers and avoids exposing implementation detail that could be misused. Legitimate integrators should use the official API docs and your NewLedger account team if you need partner access.",[796,1249,1251],{"id":1250},"oauth-20-flow-at-a-glance","OAuth 2.0 flow at a glance",[52,1253,1254,1267],{},[55,1255,1256],{},[58,1257,1258,1261,1264],{},[61,1259,1260],{},"Step",[61,1262,1263],{},"Who",[61,1265,1266],{},"What happens",[68,1268,1269,1280,1291,1302],{},[58,1270,1271,1274,1277],{},[73,1272,1273],{},"1",[73,1275,1276],{},"Client (e.g. ChatGPT)",[73,1278,1279],{},"Opens NewLedger sign-in and consent using PKCE",[58,1281,1282,1285,1288],{},[73,1283,1284],{},"2",[73,1286,1287],{},"You",[73,1289,1290],{},"Review company and permissions in the app, then confirm with 2FA",[58,1292,1293,1296,1299],{},[73,1294,1295],{},"3",[73,1297,1298],{},"NewLedger",[73,1300,1301],{},"Records the approved connection with a scoped permission set",[58,1303,1304,1307,1310],{},[73,1305,1306],{},"4",[73,1308,1309],{},"Client",[73,1311,1312],{},"Calls the allowed NewLedger surface only within that scope",[47,1314,1316],{"id":1315},"quick-comparison","Quick comparison",[52,1318,1319,1329],{},[55,1320,1321],{},[58,1322,1323,1325,1327],{},[61,1324],{},[61,1326,80],{},[61,1328,90],{},[68,1330,1331,1344,1357,1369,1380,1391],{},[58,1332,1333,1338,1341],{},[73,1334,1335],{},[21,1336,1337],{},"Typical use",[73,1339,1340],{},"Automations, ETL, partner APIs, internal tools",[73,1342,1343],{},"MCP clients, partner apps, or delegated user connections",[58,1345,1346,1351,1354],{},[73,1347,1348],{},[21,1349,1350],{},"Setup UI",[73,1352,1353],{},"API Credentials tab",[73,1355,1356],{},"Client registration, consent flow, and OAuth Connections tab",[58,1358,1359,1364,1366],{},[73,1360,1361],{},[21,1362,1363],{},"User consent screen",[73,1365,369],{},[73,1367,1368],{},"Yes (in-app OAuth consent)",[58,1370,1371,1375,1377],{},[73,1372,1373],{},[21,1374,377],{},[73,1376,369],{},[73,1378,1379],{},"Yes (must match the MCP client exactly)",[58,1381,1382,1386,1388],{},[73,1383,1384],{},[21,1385,202],{},[73,1387,369],{},[73,1389,1390],{},"Yes (S256)",[58,1392,1393,1398,1401],{},[73,1394,1395],{},[21,1396,1397],{},"How the client gets a token",[73,1399,1400],{},"Server-side exchange with client secret",[73,1402,1403],{},"User approval, then client completes OAuth",[11,1405,1406,1407,1410,1411,251],{},"Both issue ",[21,1408,1409],{},"App Connect bearer tokens"," under the same permission model. The difference is ",[21,1412,1413],{},"who holds the secret and whether the user must approve the connection in a browser",[47,1415,1417],{"id":1416},"security-defaults-worth-knowing","Security defaults worth knowing",[11,1419,1420],{},[21,1421,80],{},[438,1423,1424,1430,1435,1441,1447],{},[18,1425,1426,1429],{},[21,1427,1428],{},"Permissions are delegated, not elevated"," — at create time, from your user's permission set.",[18,1431,1432,1434],{},[21,1433,816],{}," — treat the client secret like a password; rotate if exposed.",[18,1436,1437,1440],{},[21,1438,1439],{},"2FA for sensitive actions"," — revoke, delete, and rotate require action confirmation.",[18,1442,1443,1446],{},[21,1444,1445],{},"Audit trail"," — token exchange failures and lifecycle events appear in workspace activity.",[18,1448,1449,1452],{},[21,1450,1451],{},"Separate non-production from production"," — use distinct apps, scopes, and owners for testing versus live finance workflows.",[11,1454,1455],{},[21,1456,1457],{},"OAuth 2.0 connections",[438,1459,1461,1467,1472,1478,1484],{"start":1460},6,[18,1462,1463,1466],{},[21,1464,1465],{},"Consent + 2FA"," before the connection is active.",[18,1468,1469,966],{},[21,1470,1471],{},"PKCE (S256)",[18,1473,1474,1477],{},[21,1475,1476],{},"HTTPS redirect URIs"," for registered OAuth clients.",[18,1479,1480,1483],{},[21,1481,1482],{},"Approve only the scopes you actually need"," — treat scope review as a finance-control step, not a formality.",[18,1485,1486,1489],{},[21,1487,1488],{},"Revoke via OAuth Connections"," — deleting a connection removes ongoing access; data already drafted in NewLedger stays for you to review.",[47,1491,1493],{"id":1492},"a-secure-rollout-looks-like-this","A secure rollout looks like this",[438,1495,1496,1503,1509,1516],{},[18,1497,1498,1499,1502],{},"Create a ",[21,1500,1501],{},"test-company connection first"," so token exchange, scopes, and workflows are proven before production.",[18,1504,449,1505,1508],{},[21,1506,1507],{},"smallest permission set"," that lets the integration do useful work.",[18,1510,1511,1512,1515],{},"Confirm the ",[21,1513,1514],{},"activity log"," shows the events finance and security teams expect to review later.",[18,1517,1518,1519,1522],{},"Record an internal ",[21,1520,1521],{},"owner, purpose, and revocation path"," for every live API credential app or OAuth connection.",[47,1524,1526],{"id":1525},"troubleshooting-workspace","Troubleshooting (workspace)",[11,1528,1529],{},[21,1530,80],{},[52,1532,1533,1543],{},[55,1534,1535],{},[58,1536,1537,1540],{},[61,1538,1539],{},"What you see",[61,1541,1542],{},"What to try",[68,1544,1545,1553,1561],{},[58,1546,1547,1550],{},[73,1548,1549],{},"Token request fails",[73,1551,1552],{},"Confirm client ID and secret, app is active, and the app was not revoked or deleted",[58,1554,1555,1558],{},[73,1556,1557],{},"Access stops after a date",[73,1559,1560],{},"Check optional credential expiry on the app",[58,1562,1563,1566],{},[73,1564,1565],{},"Scope or permission errors",[73,1567,1568],{},"Ensure the permission is delegated on the app and your user role allows it",[11,1570,1571],{},[21,1572,90],{},[52,1574,1575,1583],{},[55,1576,1577],{},[58,1578,1579,1581],{},[61,1580,1539],{},[61,1582,1542],{},[68,1584,1585,1593,1605,1613],{},[58,1586,1587,1590],{},[73,1588,1589],{},"Consent does not finish",[73,1591,1592],{},"Complete 2FA on the consent screen; do not skip the in-app approval step",[58,1594,1595,1598],{},[73,1596,1597],{},"ChatGPT cannot connect",[73,1599,1600,1601,1604],{},"Confirm the MCP URL is for the correct company; reconnect from ",[21,1602,1603],{},"Integrations"," or App Connect",[58,1606,1607,1610],{},[73,1608,1609],{},"Redirect or registration errors",[73,1611,1612],{},"Redirect URI must match the MCP client exactly (copy from ChatGPT, do not type from memory)",[58,1614,1615,1618],{},[73,1616,1617],{},"Connection still listed but client fails",[73,1619,1620],{},"Delete the OAuth connection and go through consent again",[11,1622,1623,1624,1627],{},"For API error details while building an integration, use the ",[326,1625,1626],{"href":543},"API documentation"," in the context of your own test company — not production credentials.",[47,1629,523],{"id":522},[15,1631,1632,1641,1649,1656,1663],{},[18,1633,1634,1637,1638,1640],{},[21,1635,1636],{},"Accounting API integration (automations, partners):"," create ",[21,1639,80],{}," under Settings → App Connect",[18,1642,1643,1646,1647],{},[21,1644,1645],{},"Choosing between connection types:"," ",[326,1648,942],{"href":941},[18,1650,1651,1646,1654],{},[21,1652,1653],{},"ChatGPT / MCP:",[326,1655,329],{"href":328},[18,1657,1658,1646,1661],{},[21,1659,1660],{},"API reference:",[326,1662,544],{"href":543},[18,1664,1665,1646,1668],{},[21,1666,1667],{},"Workspace:",[326,1669,1672],{"href":1670,"rel":1671},"https://app.newledger.io",[629],"NewLedger app",[11,1674,1675,1676,1678,1679,1681],{},"Accounting API integration should make operations faster without weakening financial control. Use ",[21,1677,80],{}," when you run the integration and can store a secret safely; use ",[21,1680,90],{}," when the client needs delegated, consent-driven access through the browser.",{"title":555,"searchDepth":556,"depth":556,"links":1683},[1684,1685,1691,1703,1704,1705,1706,1707],{"id":640,"depth":556,"text":641},{"id":785,"depth":556,"text":786,"children":1686},[1687,1689,1690],{"id":798,"depth":1688,"text":799},3,{"id":832,"depth":1688,"text":833},{"id":906,"depth":1688,"text":907},{"id":923,"depth":556,"text":924,"children":1692},[1693,1694,1695,1696,1697,1698,1699,1700,1701,1702],{"id":946,"depth":1688,"text":947},{"id":977,"depth":1688,"text":978},{"id":984,"depth":1688,"text":985},{"id":1016,"depth":1688,"text":1017},{"id":1023,"depth":1688,"text":1024},{"id":1069,"depth":1688,"text":1070},{"id":1076,"depth":1688,"text":1077},{"id":1115,"depth":1688,"text":1116},{"id":1186,"depth":1688,"text":1187},{"id":1250,"depth":1688,"text":1251},{"id":1315,"depth":556,"text":1316},{"id":1416,"depth":556,"text":1417},{"id":1492,"depth":556,"text":1493},{"id":1525,"depth":556,"text":1526},{"id":522,"depth":556,"text":523},{"src":873,"alt":1709,"credit":570},"NewLedger App Connect API credentials list showing connected apps and delegated permissions","2026-05-26",{"contributors":1712},[6],"/blog/2026/05/26-accounting-api-integration",{"title":1715,"description":1716,"image":873},"Scaling operations via accounting APIs | NewLedger","Accounting API integration on NewLedger for SMBs: use App Connect API credentials for server-side automations and OAuth 2.0 for delegated, consent-based client access.","accounting-api-integration","blog/2026/05/26-accounting-api-integration","How high-performance platforms leverage unified ledger infrastructure to achieve forensic precision, eliminate engineering debt, and build programmable financial workflows.",[1721,1722,1723,586,590,1724,1725,592,587,588,589,593,591,1726],"accounting","accounting-api","accounting-software","smb","small-business","operations","UHFNBp-nisfT52Nbmls8V6coBPw2vHk6H1zggEjXe4c",1781487897398]