# Inth Full Context > All generated markdown documentation pages flattened into one file. ## Included Pages - [Inth Docs](https://inth-docs.vercel.app/docs): Learn how to use Inth Agent, audits, and hosted consent infrastructure. - [Inth Agent](https://inth-docs.vercel.app/docs/agent): Ask privacy, compliance, and consent questions with cited sources. - [Code Audit](https://inth-docs.vercel.app/docs/code-audit): Connect a GitHub repository and review privacy risks in source code. - [Consent](https://inth-docs.vercel.app/docs/consent): Hosted consent infrastructure for c15t applications. - [IAB TCF](https://inth-docs.vercel.app/docs/consent/concepts/iab-tcf): Use Inth Consent for IAB TCF projects and vendor-level consent. - [Platform](https://inth-docs.vercel.app/docs/consent/concepts/platform): How Inth hosted consent infrastructure works. - [Policy Packs](https://inth-docs.vercel.app/docs/consent/concepts/policy-packs): Resolve consent behavior by region, country, and fallback policy. - [Getting Started](https://inth-docs.vercel.app/docs/consent/getting-started): Connect your app to Inth consent management. - [Connect c15t](https://inth-docs.vercel.app/docs/consent/guides/connect-c15t): Point an existing c15t integration at Inth-hosted infrastructure. - [Consent Records](https://inth-docs.vercel.app/docs/consent/guides/consent-records): Review consent events, subjects, policies, and analytics. - [Create a Consent Project](https://inth-docs.vercel.app/docs/consent/guides/create-project): Set up hosted consent infrastructure for an app. - [Hosted Backend](https://inth-docs.vercel.app/docs/consent/reference/backend): How apps talk to the Inth consent backend. - [Glossary](https://inth-docs.vercel.app/docs/glossary): Common Inth Consent terms and how to use them. - [Pricing](https://inth-docs.vercel.app/docs/pricing): Inth plans, Credits, Consent plans, usage allowances, and billing safeguards. - [REST API](https://inth-docs.vercel.app/docs/rest-api): Machine-facing control-plane API for Inth projects, API keys, device authorization, and MCP access. - [Start CLI device authorization](https://inth-docs.vercel.app/docs/rest-api/auth/create-device-authorization-request): Creates a short-lived PKCE-bound device authorization request for the Inth CLI. This endpoint is only available when CLI device authorization is enabled. - [Delete API key](https://inth-docs.vercel.app/docs/rest-api/auth/delete-api-key): Revokes an organization API key. Requires an owner or admin session/OAuth principal; API keys cannot delete keys. - [Get authenticated principal](https://inth-docs.vercel.app/docs/rest-api/auth/get-me): Get authenticated principal - [List API keys](https://inth-docs.vercel.app/docs/rest-api/auth/list-api-keys): Lists the API keys of an organization. Keys are organization credentials; without organizationId the active organization is used. - [Poll for a CLI device token](https://inth-docs.vercel.app/docs/rest-api/auth/poll-device-authorization-token): Redeems an approved device code once. A 409 authorization_pending response is expected until a person approves the code. - [Roll API key](https://inth-docs.vercel.app/docs/rest-api/auth/roll-api-key): Replaces the key secret while keeping its name and identity in the key list. The previous secret stops working immediately. The new secret is minted with the current plan tier rate limit and is returned only once. Requires an owner or admin session/O… - [Rate limits](https://inth-docs.vercel.app/docs/rest-api/limits): Per-key API rate limits by plan, rate limit response headers, request size caps, and how to handle 429 responses. - [List organizations](https://inth-docs.vercel.app/docs/rest-api/organizations/list-organizations): List organizations - [Create project](https://inth-docs.vercel.app/docs/rest-api/projects/create-project): Creates a project and provisions its initial consent instance. - [Delete project](https://inth-docs.vercel.app/docs/rest-api/projects/delete-project): Archives the project and linked active consent instances for the authenticated organization. - [Get project](https://inth-docs.vercel.app/docs/rest-api/projects/get-project): Get project - [Get project consent settings](https://inth-docs.vercel.app/docs/rest-api/projects/get-project-consent): Get project consent settings - [List projects](https://inth-docs.vercel.app/docs/rest-api/projects/list-projects): List projects - [List provisioning regions](https://inth-docs.vercel.app/docs/rest-api/projects/list-regions): List provisioning regions - [Update project](https://inth-docs.vercel.app/docs/rest-api/projects/update-project): Updates project metadata. Changing projectName also updates the project slug. - [Update project consent settings](https://inth-docs.vercel.app/docs/rest-api/projects/update-project-consent): Partially updates consent settings on the instance linked to this project. - [Health check](https://inth-docs.vercel.app/docs/rest-api/system/get-health): Health check - [Website Audit](https://inth-docs.vercel.app/docs/website-audit): Scan a production website for vendors, cookies, and runtime evidence. ## Content # Inth Docs URL: https://inth-docs.vercel.app/docs Learn how to use Inth Agent, audits, and hosted consent infrastructure. Inth helps teams investigate privacy questions, find risks in code, observe production websites, and run hosted consent infrastructure. These docs explain how to use Inth Agent, Code Audit, Website Audit, and Consent. They focus on product behavior, setup, configuration, and interpreting results. Pricing details appear only where they are needed to understand the workflow. ## c15t docs are canonical c15t owns the frontend framework docs, component APIs, hooks, styling, script loading, iframe blocking, internationalization, IAB TCF component behavior, and self-hosting guides. Use [c15t.com/docs](https://c15t.com/docs) for those topics. Inth docs explain the hosted platform, including what changes when a c15t app uses Inth-hosted infrastructure. ## Start here * [Inth Agent](/docs/agent): ask privacy, compliance, and consent questions with cited sources. * [Inth Code Audit](/docs/code-audit): connect GitHub and review privacy risks in source code. * [Inth Website Audit](/docs/website-audit): scan a production website for vendors, cookies, and runtime evidence. * [Getting started](/docs/consent/getting-started): choose your integration path and connect an app to Inth. * [Consent](/docs/consent): learn the released hosted consent platform. * [Create a consent project](/docs/consent/guides/create-project): set up hosted consent infrastructure for an app. * [Platform concepts](/docs/consent/concepts/platform): understand how the dashboard, hosted runtime, and c15t SDK work together. * [IAB TCF](/docs/consent/concepts/iab-tcf): understand the managed CMP layer for eligible Consent projects. * [Connect c15t](/docs/consent/guides/connect-c15t): point a c15t integration at Inth-hosted consent infrastructure. * [Consent records](/docs/consent/guides/consent-records): review consent events, subjects, policies, and analytics. ## Inth Consent and c15t c15t is the open-source consent framework. Inth provides the hosted runtime around it: project configuration, trusted origins, region-aware policy resolution, durable storage, and managed infrastructure. For most production apps, use hosted mode with a consent backend URL or app-local proxy. Use offline mode for local prototypes only, because it stores consent in the browser and does not create backend audit history. # Inth Agent URL: https://inth-docs.vercel.app/docs/agent Ask privacy, compliance, and consent questions with cited sources. Inth Agent is an organization-scoped research agent for privacy, compliance, and consent implementation questions. It can help you understand legal requirements, map them to c15t and Inth, and work through findings from your Inth Inbox. > ℹ️ **Info:** **Limited beta** > Inth Agent is currently available only to selected organizations. If Inth Agent does not appear in the dashboard, your organization does not currently have access. Inth Agent provides legal information, not legal advice. Review important conclusions with your privacy or legal team. ## Open Inth Agent Inth Agent does not need a separate connection: 1. Sign in to the Inth dashboard and select an organization. 2. Open **Inth Agent** in the sidebar. 3. Select **New agent**. 4. Enter a question or choose a suggested prompt. The first message creates a saved agent. Your recent agents appear under **Inth Agent** in the sidebar and are tied to your user account within the selected organization. ## Research answers Every substantive legal and compliance question uses the same sourced research workflow. Focused questions usually finish faster, while broader or comparative questions may require more source work. ## Ask effective questions Include the facts that could change the answer: * the countries or regions involved * the type of personal data * what your product collects, stores, or shares * the vendor, SDK, cookie, or integration involved * the decision you need to make You can ask about topics such as GDPR and UK GDPR, CCPA and CPRA, consent, cookies, data rights, breach response, and c15t implementation. ### Ask Inth Agent about an Inbox finding To investigate an existing finding, open it in **Inbox** and select **Ask Inth Agent**. Inth creates an agent record with the finding summary and available code or runtime context included in the prompt. This is the most reliable way to give Inth Agent product-specific context. A normal new agent does not automatically read every repository, website, or audit in your organization. ## Review an answer Where source material is available, Inth Agent shows citations you can open and verify. Check that: * the source applies to the relevant jurisdiction and date * the answer distinguishes a legal requirement from a recommended practice * any assumptions match how your product actually works * product-specific claims are supported by the attached finding or details you provided You can stop a response while it is running, copy an answer, or regenerate the latest response. ## Credits and response time Inth Agent uses Credits for completed responses. Credit use depends on the work needed to answer the question. Inth checks your organization's balance before starting a response. If the balance is too low, add Credits and retry the message. Failed or cancelled responses do not use Credits. Broader questions can take longer because they require more source work. A focused question with an explicit jurisdiction and date usually completes faster. # Code Audit URL: https://inth-docs.vercel.app/docs/code-audit Connect a GitHub repository and review privacy risks in source code. Inth Code Audit finds code-evidenced privacy and data-protection risks in a repository. It combines deterministic code signals with investigation of the surrounding data flow, then produces findings that engineering, privacy, security, and legal teams can review. > ℹ️ **Info:** **Limited beta** > Inth Code Audit is currently available only to selected organizations. If Code Audit does not appear in the dashboard, your organization does not currently have access. Code Audit can identify areas such as: * personal or sensitive data written to logs and observability tools * analytics, advertising, replay, or identity tools loaded before consent * retention, deletion, DSAR, and data-export gaps * personal data sent to vendors, webhooks, CRMs, or AI services * privacy-relevant changes introduced by a pull request Code Audit does not make final legal conclusions. Its findings are evidence for review. ## Before you start You need: * an Inth organization and project * an organization owner or admin who can connect the Inth GitHub App * access to the repository you want to audit * enough Inth Credits for the audit you want to run Adding the project's production website and public policy pages is recommended. This gives Code Audit context about your disclosures and intended privacy controls, but it does not block a scan. ## Connect a repository 1. In the Inth dashboard, open **Audit**. 2. Open the project that owns the code. 3. Under **Code**, select **Connect GitHub**. 4. Complete the GitHub App installation and choose the repositories Inth may access. 5. Return to the project and link a repository. 6. Set the **Root directory**. Use `/` for the whole repository or a subdirectory for one app in a monorepo. 7. Set the production branch if it is not the repository default. GitHub shows the permissions requested by the App before installation. Repository access can be managed later from the project's Code settings. ## Add policy context Policy context helps Code Audit compare code evidence with the controls and disclosures intended for the product. From the project's Audit page: 1. Add the production website. 2. Add public pages such as your privacy policy, cookie policy, terms, or subprocessor list. 3. Save the website and policy pages. Keep these URLs current. Inth reads policy context from the active website connected to the project. ## Run a full repository audit 1. Open **Audit** and select **Run audit**. 2. Choose the connected repository. 3. Confirm that it is linked to the correct project and root directory. 4. Select **Get quote**. 5. When planning finishes, review the Credit quote and planned file count. 6. Select **Start full audit**. Planning is free. The full audit starts only after you approve the quote. Inth prevents another full audit from starting for the same repository while one is already active. Use **Audit → History** to monitor queued, running, investigating, and completed audits or to return to a quote that is ready for approval. ## Time and Credit expectations Full Code Audits are one of the more Credit-intensive operations in Inth. Repository size, the selected scope, and the amount of privacy-relevant code all affect the work required. Large or complex repositories can take more than an hour to complete. Use a project root directory to avoid auditing unrelated apps in a monorepo, and check the quote before starting the full run. The dashboard shows a Credit quote for the planned scope before you approve the full audit. ## Configure pull request scans To review changes before merge: 1. Open **Integrations** and select the connected repository, or open the repository settings from the **Run audit** sheet. 2. Enable **Scan pull requests**. 3. Optionally add PR branch filters such as `main` or `release/*`, one per line. 4. Optionally add ignored PR paths such as `docs/**`, one path or glob per line. Branch and path filters support wildcards, including `**` for nested directories. Leave the branch field empty to scan pull requests for every branch. Pull request automation is managed by the first Inth organization that connected the repository. Other linked organizations can still run manual audits. Scheduled full-repository Code Audits are not currently available. Each pull request scan reviews the files GitHub currently includes in the PR diff after project-root and ignored-path filtering. It does not rescan the whole repository, but it does review the full current PR diff rather than only files from the latest push. Ordinary duplicate webhook deliveries reuse the current run. A newer head supersedes older work, and only the current head can publish its check and review. Deduplication is scoped to one pull request. If changes from a reviewed branch later appear in a stacked or long-lived integration PR, they can be reviewed again while GitHub still includes them in that PR's diff. ## Pull request scan Credits One Inth Credit is $0.10. A successfully settled pull request scan costs a 50-Credit ($5) platform fee plus the reconciled AI provider cost priced at a 30% gross margin, rounded up to a whole Credit. The final amount is known after the provider reports the run's usage. Inth keeps the completed report private until the full Credit amount settles. If the organization has enough Credits for the platform fee but not the final provider-cost balance, the platform fee is charged and the report remains locked until an owner adds Credits. Inth automatically retries settlement and publishes the existing scan after the top-up; the audit does not run again. Failed, cancelled, and superseded scans do not settle the full successful-scan price. ## Review the report A completed report identifies the repository, branch, commit, and scanned directory. Findings can include: * priority and review state * affected files and source lines * supporting source evidence * the relevant data flow or control area * remediation or review guidance Start with critical and high-priority items, but treat priority as potential impact rather than proof of a legal violation. Review the cited code in context, confirm assumptions with the code owner, and record whether the finding is confirmed, fixed, not evidenced, or accepted as a risk. If investigation coverage is incomplete, the report says so. Retry the audit before treating missing findings as evidence that the repository is clear. ## Coverage and limitations JavaScript and TypeScript have the broadest validated analysis coverage. Go, Python, Astro, Vue, and Svelte coverage is currently preview-stage, and some privacy-relevant behavior may require manual review. Code Audit can miss behavior hidden behind runtime configuration, external systems, generated code, or unsupported languages. A clean report is not a compliance certificate or a guarantee that every privacy risk has been found. # Consent URL: https://inth-docs.vercel.app/docs/consent Hosted consent infrastructure for c15t applications. Inth Consent is the hosted platform layer around c15t. Your app keeps native c15t UI and framework control; Inth runs the managed infrastructure for policy resolution, trusted origins, consent syncing, and consent records. Use this section for Inth-specific platform work. Use [c15t.com/docs](https://c15t.com/docs) for component APIs, framework setup, styling, script loading, iframe blocking, internationalization, IAB TCF component behavior, and self-hosting. ## Start here * [Getting started](/docs/consent/getting-started): connect an app to hosted consent infrastructure. * [Create a consent project](/docs/consent/guides/create-project): configure the hosted project and trusted origins. * [Connect c15t](/docs/consent/guides/connect-c15t): point an existing c15t integration at Inth. * [Policy packs](/docs/consent/concepts/policy-packs): understand region-aware consent behavior. * [IAB TCF](/docs/consent/concepts/iab-tcf): use Inth as the managed CMP layer for eligible TCF projects. * [Consent records](/docs/consent/guides/consent-records): inspect saved consent activity. # IAB TCF URL: https://inth-docs.vercel.app/docs/consent/concepts/iab-tcf Use Inth Consent for IAB TCF projects and vendor-level consent. IAB TCF is for publishers and teams whose advertising, measurement, or monetization partners require the IAB Europe Transparency and Consent Framework. For eligible Consent projects, Inth can provide the managed CMP layer for IAB TCF while your application keeps the c15t-rendered consent experience. That gives teams a hosted path instead of registering, operating, and maintaining their own CMP implementation directly. The TCF expects participating CMPs to be registered. Inth's IAB TCF add-on gives eligible projects an Inth-managed registered-CMP path for TCF consent flows. ## What Inth provides Inth manages the hosted platform layer around an IAB TCF consent project: * project-level IAB TCF enablement * hosted policy resolution for TCF regions * vendor-list configuration in the consent project * Consent Sessions for region-aware runtime behavior * consent saves and durable consent records * trusted-origin checks for connected applications * operational support for unusual usage or consent-record behavior Use Inth docs for the hosted CMP layer, project setup, add-on billing, trusted origins, policy packs, Consent Sessions, and consent records. ## What your app provides Your app still renders the banner, dialog, widgets, and surrounding consent UX with c15t. Use c15t docs for frontend package setup, framework-specific components, styling, script loading, iframe blocking, internationalization, and the browser behavior of IAB TCF components. ## When to enable IAB TCF Enable IAB TCF when your consent program needs TCF signals for advertising, publishing, measurement, or vendor-level consent in covered regions. Do not enable IAB TCF just because a site uses analytics. Standard consent policies are usually simpler when your partners do not require the IAB vendor framework. ## Setup overview 1. Create a [Consent project](/docs/consent/guides/create-project). 2. Enable the IAB TCF add-on for that project. 3. Configure trusted origins for the application. 4. Configure IAB vendors and any required non-IAB disclosures. 5. Use a policy pack that includes IAB TCF behavior for the regions that need it. 6. Connect your c15t app to the hosted project. 7. Save a test consent choice and confirm the consent record appears in Inth. ## Pricing IAB TCF is billed as a project add-on. See [Pricing](/docs/pricing) for the current public billing model. ## Compliance boundary Inth helps provide managed CMP infrastructure and recordkeeping for IAB TCF projects. Your organization still owns its privacy program, vendor selection, legal basis choices, disclosures, policy copy, and legal review. Depending on your role, you may also have separate responsibilities as a publisher, vendor, advertiser, or other participant in the advertising ecosystem. ## External references * [IAB Europe TCF for CMPs](https://iabeurope.eu/tcf-for-cmps/) * [IAB Europe CMP list](https://iabeurope.eu/cmp-list/) # Platform URL: https://inth-docs.vercel.app/docs/consent/concepts/platform How Inth hosted consent infrastructure works. Inth separates consent UX from consent infrastructure. Your app owns the React components and visual experience. Inth hosts the runtime services that resolve policy, store consent, and serve the backend API that c15t clients call. ## Core pieces **Application** Your site installs a c15t client package, mounts `ConsentManagerProvider`, and renders a banner, dialog, widget, or headless UI. The app also configures scripts, iframes, and other integrations that should wait for consent. **Inth dashboard** The dashboard stores project configuration: trusted origins, runtime region, enabled features, branding, policy packs, IAB settings, and custom translations when enabled. **Hosted runtime** The hosted runtime checks trusted origins, resolves the active project configuration, and connects c15t clients to managed consent services. **c15t backend** The backend resolves the visitor's policy, returns banner/dialog data, stores consent records, and supports server-side awareness for applications that need consent state outside the browser. ## Consent lifecycle 1. The client initializes and requests backend data. 2. The backend resolves location, jurisdiction, translations, policy packs, and the active consent model. 3. The UI decides whether a banner or dialog should be shown. 4. The visitor accepts, rejects, or customizes choices. 5. Consent is saved locally, synced to the backend, and applied immediately to scripts, iframes, network requests, and app code that subscribes to consent changes. ## Production defaults Use hosted mode for production. It gives you centralized policy resolution, durable records, location-aware behavior, and backend synchronization. Offline mode is useful for demos and local prototypes, but it does not provide the backend guarantees that production consent programs usually need. # Policy Packs URL: https://inth-docs.vercel.app/docs/consent/concepts/policy-packs Resolve consent behavior by region, country, and fallback policy. Policy packs describe which consent model, categories, UI behavior, legal links, and actions apply for a visitor. In hosted mode, the hosted runtime resolves the active policy for each Consent Session. ## How resolution works The hosted runtime evaluates policy match rules against visitor context such as region and country. A typical setup includes: * region-specific policies for areas like the EEA * country-specific overrides * fallback policies * a default policy for everyone else The resolved policy controls whether the visitor sees an opt-in, opt-out, IAB TCF, or no-banner experience. ## What can change consent behavior Material changes to a policy can re-prompt users. Examples include changing the consent model, changing categories, changing allowed actions, or changing scope behavior. Presentation-only changes should not be treated the same as consent-affecting changes. Keep copy, layout, and visual updates separate from changes that alter what the visitor is agreeing to. ## Global Privacy Control When a policy uses opt-out or no-banner behavior, Global Privacy Control can still deny measurement or marketing categories when the browser sends the signal and the policy is configured to respect it. ## IAB policies Use IAB policies only when your consent program requires the IAB TCF flow. Inth can provide the managed CMP layer for eligible IAB TCF projects, while your app renders the IAB banner and dialog from the c15t IAB packages. See [IAB TCF](/docs/consent/concepts/iab-tcf) for the Inth platform boundary. # Getting Started URL: https://inth-docs.vercel.app/docs/consent/getting-started Connect your app to Inth consent management. Use Inth when you want c15t consent UX with a hosted backend for policy resolution, consent syncing, jurisdiction awareness, and durable records. ## What you need Before connecting an app, create a consent project in Inth and decide which application origins should be allowed to call it. Then use c15t's canonical framework docs for the frontend integration: * [Next.js quickstart](https://c15t.com/docs/frameworks/next/quickstart) * [React quickstart](https://c15t.com/docs/frameworks/react/quickstart) * [JavaScript quickstart](https://c15t.com/docs/frameworks/javascript/quickstart) ## Inth-specific setup Inth changes the backend side of the setup: * create a managed consent project * choose a runtime region * add trusted origins * use hosted mode in c15t * set `backendURL` to your consent backend URL or app proxy The app-local proxy pattern is common: ```ts backendURL: '/api/c15t'; ``` The hosted backend is responsible for jurisdiction and policy resolution, consent syncing, and backend records. Keep `mode="hosted"` for production. ## Verify the install 1. Start your app locally. 2. Confirm the banner appears when no consent has been saved. 3. Open the customize dialog and verify each configured category appears. 4. Accept or reject consent, reload, and confirm the choice persists. 5. Check that measurement and marketing scripts do not run until their category is granted. 6. Confirm the save appears in Inth consent records. # Connect c15t URL: https://inth-docs.vercel.app/docs/consent/guides/connect-c15t Point an existing c15t integration at Inth-hosted infrastructure. Use c15t docs for framework setup, component APIs, hooks, styling, translations, script gating, iframe blocking, and IAB TCF component behavior. This page only covers the Inth-specific connection points. ## Configure hosted mode In production, use hosted mode and point `backendURL` at your Inth-hosted consent backend. ```ts { mode: 'hosted', backendURL: '/api/c15t' } ``` `/api/c15t` is an application-local proxy pattern. If your deployment uses a project backend URL directly, set `backendURL` to that URL. ## Match trusted origins The origin serving your app must be listed on the Inth consent project. Include production, preview, staging, and local origins that need browser access to the backend. If c15t initializes locally but fails against hosted infrastructure, check trusted origins first. ## Keep categories consistent The categories configured in your c15t app should match the policy behavior you manage in Inth. For example, if the app gates analytics under `measurement`, make sure the active policies expose that category where required. ## Use c15t for frontend behavior Go to [c15t.com/docs](https://c15t.com/docs) for: * framework quickstarts * `ConsentManagerProvider` * banners, dialogs, widgets, and triggers * `useConsentManager` * script loading and iframe blocking * styling and slots * internationalization * IAB TCF frontend behavior * self-hosting c15t Use Inth docs when the question is about the hosted project, backend URL, origins, policy resolution, records, runtime behavior, or the managed IAB TCF CMP layer. # Consent Records URL: https://inth-docs.vercel.app/docs/consent/guides/consent-records Review consent events, subjects, policies, and analytics. Hosted mode stores consent activity in the backend so teams can inspect what happened after a visitor interacts with a banner or dialog. ## What a record shows Consent records can include: * subject ID * external ID when supplied by the app * policy * captured purposes or categories * user action * capture time * country and region * language Use records to debug integration issues, confirm that policies are being resolved as expected, and inspect the consent state associated with a subject. ## Search and filter Use search and pagination when reviewing large sets of records. Start with the subject or external ID when you are investigating one user. Filter by policy or date range when you are validating a rollout. ## Overview analytics The consent overview helps you understand aggregate behavior: * total consent volume * accept, customize, and reject split * consent rates by policy * changes over a selected date range Analytics are operational signals, not legal conclusions. Use them to spot implementation issues, policy changes, or unexpected changes in consent behavior. ## Common checks After shipping a new consent integration: 1. Save each banner action in a test browser. 2. Confirm the expected consent records appear. 3. Check that the resolved policy matches the test region. 4. Verify category values line up with script behavior. 5. Reopen privacy settings, change preferences, and confirm the new record state. # Create a Consent Project URL: https://inth-docs.vercel.app/docs/consent/guides/create-project Set up hosted consent infrastructure for an app. A consent project connects your application to an Inth-hosted c15t backend. The project stores runtime configuration and gives your app a backend URL for hosted mode. ## Create the project In the dashboard, create a consent project and choose: * project name * runtime region * trusted origins The dashboard chooses the managed runtime for new consent projects. ## Choose a region Pick the region that best matches your application, users, and data-residency needs. The region determines where hosted consent services run for the project. ## Add trusted origins Trusted origins control which websites can call the hosted consent backend from the browser. Add every origin that needs access: * production domain * preview deployment domains * local development origin * staging or QA domains Avoid broad wildcards unless they are intentional. Wildcards make setup easier for preview URLs, but they also widen the set of origins that can call the instance. ## Connect your app After the project exists, point your app at the consent backend URL or an application-local proxy. ```ts { mode: 'hosted', backendURL: '/api/c15t' } ``` Many apps proxy `/api/c15t` to the managed consent backend so application code can keep a stable internal path across environments. ## Next steps * Configure policy packs for the regions you serve. * Add a persistent privacy settings link. * Verify consent records appear after test saves. * Confirm measurement and marketing scripts wait for consent. # Hosted Backend URL: https://inth-docs.vercel.app/docs/consent/reference/backend How apps talk to the Inth consent backend. In hosted mode, c15t clients call your project's consent backend URL. Many apps use an application-local proxy such as `/api/c15t` so application code stays stable across environments. ## Responsibilities The hosted backend handles: * initialization data for the client * location and jurisdiction context * policy-pack resolution * translations and UI configuration * consent writes and sync * server-side consent awareness ## Origins Each consent project has trusted origins. The hosted runtime checks the request origin before serving browser consent requests. Add every production, preview, and local origin that should be allowed to call the project. ## Operational checks Use the dashboard and consent records to confirm that requests reach the expected project, policies resolve as expected, and trusted origins are configured correctly. ## Keep the backend URL configurable Application code should depend on the c15t client contract and keep the backend URL configurable across local, preview, staging, and production environments. # Glossary URL: https://inth-docs.vercel.app/docs/glossary Common Inth Consent terms and how to use them. These terms describe the released Consent side of Inth. ## Consent Sessions Hosted consent checks that resolve the right consent experience for a visitor. Consent Sessions are not the same as page views. ## Consent saves Durable consent writes created when a visitor accepts, rejects, customizes, or updates preferences. ## Hosted mode The c15t client mode used when an application talks to an Inth-hosted backend. Hosted mode is the production default for Inth Consent because it supports policy resolution, backend records, trusted origins, and server-backed synchronization. ## Offline mode The c15t client mode that stores consent locally in the browser. Use offline mode for local prototypes, static demos, tests, and fallback scenarios. Do not position it as equivalent to hosted mode for production consent programs. ## Consent project An Inth dashboard project that connects an application to hosted consent infrastructure. A consent project stores runtime configuration such as trusted origins, runtime region, policy packs, and enabled consent features. ## Trusted origins The application origins allowed to call a hosted consent backend from the browser. Add production, preview, staging, and local origins that need access. Avoid broad wildcards unless they are intentional. ## Policy pack A managed set of consent policies that determines which consent model, categories, UI behavior, legal links, and actions apply for a visitor. Policy packs let teams manage region-aware behavior without changing frontend component code for every policy change. ## IAB TCF The IAB Europe Transparency and Consent Framework. Use Inth's IAB TCF docs for the hosted platform layer and managed CMP boundary. Use c15t docs for frontend IAB TCF package and component behavior. ## Managed CMP layer The Inth-hosted platform layer for eligible IAB TCF Consent projects. The managed CMP layer can help teams use an Inth-managed registered-CMP path for IAB TCF without directly registering, operating, and maintaining their own CMP implementation. It does not replace the customer's privacy program, vendor choices, disclosures, or legal review. ## Runtime region The region where hosted consent services run for a project. Choose a runtime region based on your application, users, and data-residency needs. ## Hosted backend The Inth-managed backend that c15t clients use in hosted mode. The hosted backend handles policy resolution, consent syncing, trusted-origin checks, configuration, and backend records. ## Automated traffic Traffic from known automated sources. Automated traffic can appear in operational analytics, but it is excluded from billable consent usage when detected. ## Usage safeguards Billing protections designed to avoid treating duplicate delivery, retry noise, and short-lived traffic spikes as separate user interactions. If usage still looks unusual, contact support so we can help review the usage pattern and next steps. # Pricing URL: https://inth-docs.vercel.app/docs/pricing Inth plans, Credits, Consent plans, usage allowances, and billing safeguards. Inth has two plan families: * **Inth plans** cover the workspace, Credits, Inth Agent, and audits. * **Consent plans** cover hosted Consent infrastructure and its usage allowances. ## Inth plans |Plan|Price|Included Credits|Includes| |--|--|--|--| |Free|$0|No recurring Credit grant|Core workspace access and one introductory Code Audit preview| |Startup|$250/month or $3,000/year|2,500 each month, or 30,000 up front each year|Continuous and scheduled audits| |Enterprise|Custom agreement|Set by agreement|Startup capabilities, Consent Pro, custom terms, onboarding, and support| Startup's monthly and annual options are the same plan with different billing and Credit schedules. Monthly organizations receive 2,500 Credits each month. Annually billed organizations receive 30,000 Credits up front each year. Included Startup Credits roll over and do not expire while the paid plan remains active. The Inth Free plan does not include a recurring Credit grant, but organization owners can add Credits when needed. Consent plans are purchased separately from Inth Free and Startup. Enterprise includes Consent Pro under its custom agreement. ## Inth Credits Credits are a shared organization balance. They can be used across projects for: * [Inth Agent](/docs/agent) * [Inth Code Audit](/docs/code-audit) * [Inth Website Audit](/docs/website-audit) Credit use depends on the product and the work requested: |Product|How Credits are handled|What affects usage| |--|--|--| |Inth Agent|A response can start at zero Credits. Completed responses charge AI Gateway cost plus 50%; failed or cancelled responses do not. A negative balance blocks the next response until top-up.|The model and research work required by the response| |Code Audit|Full-repository planning is free and shows a quote before approval. Pull request scans settle after provider usage is known.|Repository or PR scope and the investigation required| |Website Audit|Credits are reserved when an audit starts and settled when it succeeds. Failed or cancelled audit reservations are released.|Crawl breadth, pages visited, and site behavior| There is no single Credit amount that applies to every request or audit. The dashboard shows the relevant balance, quote, or top-up prompt before work starts. ### Code Audit pull request pricing One Credit is $0.10. A successfully settled pull request scan costs: ```text 50 Credits + ceil(AI provider cost in USD micros / 70,000) ``` The first 50 Credits are the $5 platform fee. The provider-cost component passes through the reconciled AI cost at a 30% gross margin and rounds up to a whole Credit. For example, $17.57 of reconciled provider usage produces a total charge of 301 Credits ($30.10). The platform fee is reserved before the scan and settles after successful analysis. Inth then settles the provider-cost balance from the usage reported for that run. If the organization cannot cover that completion balance, the platform fee remains charged and the report stays locked until Credits are added. Inth automatically retries the existing settlement after a top-up; failed, cancelled, and superseded scans release unsettled reservations instead of charging the full successful-scan amount. ### View and add Credits Open **Billing** in the Inth dashboard to view: * the organization's current Credit balance * settled usage for Inth Agent, Code Audit, and Website Audit * which user or automation initiated the work * recent Credit purchases and invoices Organization owners can select **Add credits**, choose an amount, and review the total before checkout. Other members can ask an owner to add Credits. Credit usage is separate from hosted Consent allowances and usage billing. ## Consent plans These plans are for hosted Consent infrastructure. They are separate from Inth Free and Startup; Consent Pro is included with Enterprise. |Plan|Monthly price|Annual billing|Projects|Support| |--|--|--|--|--| |Free|$0/mo|-|1 project|Community + docs| |Starter|$20/mo|$200/year|3 projects|Community + docs| |Pro|$50/mo|$500/year|Unlimited|Standard support| ## Included usage Consent usage is measured with two meters: |Meter|Free|Starter|Pro| |--|--|--|--| |Consent Sessions|5,000/month|25,000/month|100,000/month| |Consent saves|5,000/month|25,000/month|100,000/month| Usage above the included amount is billed at $0.001 per billable Consent Session or consent save unless an Enterprise agreement specifies different terms. ## What counts Inth meters hosted consent activity, not page views. Consent Sessions represent hosted consent checks needed to resolve the right consent experience for a visitor. Consent saves represent durable consent writes, such as accepting, rejecting, customizing, or updating preferences. Only successful hosted consent activity is eligible for usage billing. Inth groups related activity so normal page reloads, retries, and repeated checks do not become a raw page-view counter. ## Automated traffic Known automated traffic is excluded from billable usage when detected. Automated traffic can still appear in operational analytics so you can understand traffic quality, but it is not included in billable consent usage. ## Usage safeguards Inth usage billing is designed to avoid charging for duplicate delivery, retry noise, and short-lived traffic spikes as if each technical event were a separate user interaction. If your usage changes unexpectedly, review consent analytics before changing implementation code. Look for duplicate consent surfaces, preview traffic, unusual automation, or repeated preference writes. If a spike still looks unusual, contact support. We can help review the usage pattern, identify likely causes, and work through next steps with you. ## IAB TCF and policy packs [IAB TCF](/docs/consent/concepts/iab-tcf) and policy packs are included with Consent Pro and Enterprise. They are not billed as separate per-project add-ons. Consent Free and Consent Starter do not include these features. ## Free plan usage billing The Free plan includes the same usage meters with a smaller allowance. If usage billing is disabled for a Free or trial organization, hosted Consent Sessions and consent-save features can be restricted until usage billing is enabled or the organization upgrades. # REST API URL: https://inth-docs.vercel.app/docs/rest-api Machine-facing control-plane API for Inth projects, API keys, device authorization, and MCP access. The Inth API is the machine-facing control plane for Inth. Use it to provision and manage projects, inspect organizations, and manage API keys — everything the dashboard does for humans, over JSON for programs. Consent is one of the products available inside an Inth project. * **Base URL** — `https://api.inth.com` * **OpenAPI spec** — [`https://api.inth.com/openapi.json`](https://api.inth.com/openapi.json) * **MCP endpoint** — `https://api.inth.com/mcp` * **Status** — [`GET /health`](/docs/rest-api/system/get-health) ## Authentication The API uses **organization API keys** — service credentials owned by an organization, not by an individual user. Pass the key as a bearer token: ```bash curl https://api.inth.com/v1/projects \ -H "Authorization: Bearer inth_..." ``` How keys work: * **Create keys in the dashboard** under Organization settings → API Keys, or with the [create key endpoint](/docs/rest-api/auth/create-api-key) using a signed-in user's credentials. The `inth_...` secret is shown once at creation. * **Keys act as the organization.** Every request runs with organization-wide access; there are no per-key scopes yet. Treat a key like a deploy credential, not a user session. * **Keys cannot manage keys.** Creating, rolling, and deleting keys always requires a user principal, so a leaked key cannot mint successors that outlive its revocation. * **Rotate with [roll](/docs/rest-api/auth/roll-api-key).** Rolling issues a new secret for the same key identity and revokes the old secret immediately. * **Plan requirements.** API access requires the Starter plan or higher — see [rate limits](/docs/rest-api/limits) for per-plan limits, plan-gating behavior, and key caps. The MCP endpoint is the exception: it uses user-delegated OAuth instead of API keys, so agents act as the signed-in user. Point an MCP client at `https://api.inth.com/mcp` and it discovers the authorization server through the [protected resource metadata](/docs/rest-api/mcp/get-mcp-protected-resource-metadata). ## Responses Every endpoint wraps its result in a stable envelope: ```json { "success": true, "data": { } } ``` List endpoints return `data` as an array plus a `pagination` object. Pass `pagination.nextCursor` back as the `cursor` query parameter to fetch the next page: ```json { "success": true, "data": [{ "projectId": "prj_123" }], "pagination": { "nextCursor": "cHJqXzEyMw", "hasMore": true } } ``` Errors use the same envelope with `success: false` and a machine-readable `error.code` (for example `UNAUTHORIZED`, `PLAN_REQUIRED`, `RATE_LIMITED`, `NOT_FOUND`); validation failures add an `error.details` array with per-field issues: ```json { "success": false, "error": { "code": "NOT_FOUND", "message": "Project not found" } } ``` Every response carries an `X-Request-Id` header — include it when reporting an issue. ## Stability Within `v1`, changes are additive: new fields, new endpoints, and new enum values may appear at any time, and clients should ignore fields they do not recognize. Breaking changes ship under a new version prefix. Resource IDs are prefixed strings — `prj_` projects, `org_` organizations, `ins_` consent instances, `key_` API keys. Treat them as opaque; the prefix only tells you what kind of resource an ID refers to. ## Endpoints ### System * [Health check](/docs/rest-api/system/get-health) — `GET /health` ### Auth * [Start CLI device authorization](/docs/rest-api/auth/create-device-authorization-request) — `POST /v1/auth/device/code` * [Poll for a CLI device token](/docs/rest-api/auth/poll-device-authorization-token) — `POST /v1/auth/device/token` * [List API keys](/docs/rest-api/auth/list-api-keys) — `GET /v1/auth/keys` * [Delete API key](/docs/rest-api/auth/delete-api-key) — `DELETE /v1/auth/keys/{keyId}` * [Roll API key](/docs/rest-api/auth/roll-api-key) — `POST /v1/auth/keys/{keyId}/roll` * [Get authenticated principal](/docs/rest-api/auth/get-me) — `GET /v1/me` ### Organizations * [List organizations](/docs/rest-api/organizations/list-organizations) — `GET /v1/organizations` ### Projects * [List projects](/docs/rest-api/projects/list-projects) — `GET /v1/projects` * [Create project](/docs/rest-api/projects/create-project) — `POST /v1/projects` * [Get project](/docs/rest-api/projects/get-project) — `GET /v1/projects/{projectId}` * [Delete project](/docs/rest-api/projects/delete-project) — `DELETE /v1/projects/{projectId}` * [Update project](/docs/rest-api/projects/update-project) — `PATCH /v1/projects/{projectId}` * [Get project consent settings](/docs/rest-api/projects/get-project-consent) — `GET /v1/projects/{projectId}/consent` * [Update project consent settings](/docs/rest-api/projects/update-project-consent) — `PATCH /v1/projects/{projectId}/consent` * [List provisioning regions](/docs/rest-api/projects/list-regions) — `GET /v1/regions` # Start CLI device authorization URL: https://inth-docs.vercel.app/docs/rest-api/auth/create-device-authorization-request Creates a short-lived PKCE-bound device authorization request for the Inth CLI. This endpoint is only available when CLI device authorization is enabled. ```http POST /v1/auth/device/code ``` Server: `https://api.inth.com` Operation ID: `createDeviceAuthorizationRequest` ## Request ### Request Body required Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`clientId`|string|required|| |`codeChallenge`|string|required|| |`codeChallengeMethod`|string|required|| JSON Schema: ```json { "type": "object", "required": [ "clientId", "codeChallenge", "codeChallengeMethod" ], "properties": { "clientId": { "type": "string", "minLength": 1 }, "codeChallenge": { "type": "string", "minLength": 1 }, "codeChallengeMethod": { "type": "string", "const": "S256" } } } ``` ## Code Examples ### cURL ```bash curl -X POST "https://api.inth.com/v1/auth/device/code" \ -H "Content-Type: application/json" \ -d '{ "clientId": "string", "codeChallenge": "string", "codeChallengeMethod": "string" }' ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/auth/device/code", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "clientId": "string", "codeChallenge": "string", "codeChallengeMethod": "string" }), }); const data = await response.json(); ``` ## Responses ### 201 Device authorization request created. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.deviceCode`|string|required|| |`data.userCode`|string|required|| |`data.client`|object|required|| |`data.client.id`|string|required|| |`data.client.name`|string|required|| |`data.client.publisher`|string|required|| |`data.expiresIn`|integer|required|| |`data.interval`|integer|required|| |`data.verificationUri`|string (uri)|required|| |`data.verificationUriComplete`|string (uri)|required|| Example: ```json { "success": true, "data": { "deviceCode": "string", "userCode": "string", "client": { "id": "string", "name": "string", "publisher": "string" }, "expiresIn": 0, "interval": 0, "verificationUri": "https://example.com", "verificationUriComplete": "https://example.com" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "deviceCode", "userCode", "client", "expiresIn", "interval", "verificationUri", "verificationUriComplete" ], "properties": { "deviceCode": { "type": "string" }, "userCode": { "type": "string" }, "client": { "type": "object", "required": [ "id", "name", "publisher" ], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "publisher": { "type": "string" } } }, "expiresIn": { "type": "integer" }, "interval": { "type": "integer" }, "verificationUri": { "type": "string", "format": "uri" }, "verificationUriComplete": { "type": "string", "format": "uri" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 413 The request body exceeds the 1 MB limit. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Delete API key URL: https://inth-docs.vercel.app/docs/rest-api/auth/delete-api-key Revokes an organization API key. Requires an owner or admin session/OAuth principal; API keys cannot delete keys. ```http DELETE /v1/auth/keys/{keyId} ``` Server: `https://api.inth.com` Operation ID: `deleteApiKey` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`keyId`|string|required|API key identifier.| ### Query Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`organizationId`|string|optional|Organization the key belongs to. Defaults to the active organization.| ## Code Examples ### cURL ```bash curl -X DELETE "https://api.inth.com/v1/auth/keys/key_123" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/auth/keys/key_123", { method: "DELETE", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 API key was revoked. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.deleted`|boolean|required|| Example: default ```json { "success": true, "data": { "deleted": true } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Get authenticated principal URL: https://inth-docs.vercel.app/docs/rest-api/auth/get-me Get authenticated principal ```http GET /v1/me ``` Server: `https://api.inth.com` Operation ID: `getMe` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/me" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/me", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Authenticated principal and accessible organizations. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.principal`|object|required|| |`data.principal.type`|"session" \|"api\_key" \|"oauth"|required|| |`data.principal.userId`|string|optional|Present for session and oauth principals. API keys are organization credentials and carry no acting user.| |`data.principal.keyId`|string|optional|| |`data.principal.organizationId`|string|optional|The organization the API key belongs to (api\_key principals only).| |`data.principal.createdBy`|string|optional|User who minted the API key. Attribution only, never authorization.| |`data.principal.activeOrganizationId`|string \|null|optional|| |`data.activeOrganizationId`|string \|null|required|| |`data.organizations`|object\[]|required|| |`data.organizations[].organizationId`|string|required|| |`data.organizations[].organizationSlug`|string|required|| |`data.organizations[].organizationName`|string|required|| |`data.organizations[].role`|string|required|| Example: default ```json { "success": true, "data": { "principal": { "type": "api_key", "keyId": "key_123", "organizationId": "org_123", "createdBy": "usr_123" }, "activeOrganizationId": "org_123", "organizations": [ { "organizationId": "org_123", "organizationSlug": "acme", "organizationName": "Acme", "role": "owner" } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "principal", "activeOrganizationId", "organizations" ], "properties": { "principal": { "type": "object", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "session", "api_key", "oauth" ] }, "userId": { "type": "string", "description": "Present for session and oauth principals. API keys are organization credentials and carry no acting user." }, "keyId": { "type": "string" }, "organizationId": { "type": "string", "description": "The organization the API key belongs to (api_key principals only)." }, "createdBy": { "type": "string", "description": "User who minted the API key. Attribution only, never authorization." }, "activeOrganizationId": { "oneOf": [ { "type": "string" }, { "type": "null" } ] } } }, "activeOrganizationId": { "oneOf": [ { "type": "string" }, { "type": "null" } ] }, "organizations": { "type": "array", "items": { "type": "object", "required": [ "organizationId", "organizationSlug", "organizationName", "role" ], "properties": { "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "organizationName": { "type": "string" }, "role": { "type": "string" } } } } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # List API keys URL: https://inth-docs.vercel.app/docs/rest-api/auth/list-api-keys Lists the API keys of an organization. Keys are organization credentials; without organizationId the active organization is used. ```http GET /v1/auth/keys ``` Server: `https://api.inth.com` Operation ID: `listApiKeys` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Query Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`organizationId`|string|optional|Organization whose keys to list. Defaults to the active organization.| |`limit`|integer|required|Page size, between 1 and 100.| |`cursor`|string|optional|Opaque cursor from the previous page’s pagination.nextCursor.| ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/auth/keys?limit=50" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/auth/keys?limit=50", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 API keys belonging to the organization. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object\[]|required|| |`data[].keyId`|string|required|| |`data[].name`|string|required|| |`data[].start`|string|optional|| |`data[].createdAt`|string (date-time)|required|| |`data[].meta`|object|optional|| |`data[].meta.createdBy`|string|optional|User who minted the key (attribution only).| |`data[].meta.createdFrom`|string|optional|| |`data[].meta.createdAt`|string (date-time)|optional|| |`pagination`|object|required|| |`pagination.nextCursor`|string \|null|required|| |`pagination.hasMore`|boolean|required|| Example: ```json { "success": true, "data": [ { "keyId": "string", "name": "string", "start": "string", "createdAt": "2024-01-15T09:30:00Z", "meta": { "createdBy": "string", "createdFrom": "string", "createdAt": "2024-01-15T09:30:00Z" } } ], "pagination": { "nextCursor": "string", "hasMore": true } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data", "pagination" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "array", "items": { "type": "object", "required": [ "keyId", "name", "createdAt" ], "properties": { "keyId": { "type": "string" }, "name": { "type": "string" }, "start": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" }, "meta": { "type": "object", "properties": { "createdBy": { "type": "string", "description": "User who minted the key (attribution only)." }, "createdFrom": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time" } }, "additionalProperties": true } } } }, "pagination": { "type": "object", "required": [ "nextCursor", "hasMore" ], "properties": { "nextCursor": { "oneOf": [ { "type": "string", "description": "Cursor for the next page; null on the last page." }, { "type": "null" } ] }, "hasMore": { "type": "boolean" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Poll for a CLI device token URL: https://inth-docs.vercel.app/docs/rest-api/auth/poll-device-authorization-token Redeems an approved device code once. A 409 authorization_pending response is expected until a person approves the code. ```http POST /v1/auth/device/token ``` Server: `https://api.inth.com` Operation ID: `pollDeviceAuthorizationToken` ## Request ### Request Body required Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`deviceCode`|string|required|| |`clientId`|string|required|| |`codeVerifier`|string|required|| JSON Schema: ```json { "type": "object", "required": [ "deviceCode", "clientId", "codeVerifier" ], "properties": { "deviceCode": { "type": "string", "minLength": 1 }, "clientId": { "type": "string", "minLength": 1 }, "codeVerifier": { "type": "string", "minLength": 1 } } } ``` ## Code Examples ### cURL ```bash curl -X POST "https://api.inth.com/v1/auth/device/token" \ -H "Content-Type: application/json" \ -d '{ "deviceCode": "string", "clientId": "string", "codeVerifier": "string" }' ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/auth/device/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ "deviceCode": "string", "clientId": "string", "codeVerifier": "string" }), }); const data = await response.json(); ``` ## Responses ### 200 One-time CLI access token. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.accessToken`|string|required|| |`data.tokenType`|string|required|| Example: ```json { "success": true, "data": { "accessToken": "string", "tokenType": "string" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "accessToken", "tokenType" ], "properties": { "accessToken": { "type": "string" }, "tokenType": { "type": "string", "const": "Bearer" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 409 The request conflicts with the current resource state. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 413 The request body exceeds the 1 MB limit. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Roll API key URL: https://inth-docs.vercel.app/docs/rest-api/auth/roll-api-key Replaces the key secret while keeping its name and identity in the key list. The previous secret stops working immediately. The new secret is minted with the current plan tier rate limit and is returned only once. Requires an owner or admin session/O… ```http POST /v1/auth/keys/{keyId}/roll ``` Server: `https://api.inth.com` Operation ID: `rollApiKey` Replaces the key secret while keeping its name and identity in the key list. The previous secret stops working immediately. The new secret is minted with the current plan tier rate limit and is returned only once. Requires an owner or admin session/OAuth principal; API keys cannot roll themselves. ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`keyId`|string|required|API key identifier.| ### Query Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`organizationId`|string|optional|Organization the key belongs to. Defaults to the active organization.| ## Code Examples ### cURL ```bash curl -X POST "https://api.inth.com/v1/auth/keys/key_123/roll" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/auth/keys/key_123/roll", { method: "POST", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 The rolled key. The plaintext secret is returned only once. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.key`|string|required|| |`data.keyId`|string|required|| Example: default ```json { "success": true, "data": { "key": "inth_••••••••••••••••", "keyId": "key_456" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "key", "keyId" ], "properties": { "key": { "type": "string" }, "keyId": { "type": "string" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Rate limits URL: https://inth-docs.vercel.app/docs/rest-api/limits Per-key API rate limits by plan, rate limit response headers, request size caps, and how to handle 429 responses. Every Inth API key has a per-key rate limit, applied when the key is created and enforced on every authenticated request. The limit depends on your organization's plan at the time the key is minted. ## Limits by plan |Plan|Requests per minute| |--|--| |Starter|600| |Pro|1,500| |Enterprise|3,000| API access requires the Starter plan or higher. On Free plans, creating a key and calling the API both return `402` with error code `PLAN_REQUIRED`. If an organization downgrades below Starter, existing keys stop working immediately but are not deleted — they resume when the plan is upgraded again. A key keeps the limit it was minted with. After a plan upgrade, [roll the key](/docs/rest-api/auth/roll-api-key) or [mint a new one](/docs/rest-api/auth/create-api-key) to pick up the higher limit. ## Rate limit headers Authenticated responses include headers so clients can pace themselves before hitting the limit: |Header|Meaning| |--|--| |`X-RateLimit-Limit`|The key's requests-per-minute limit.| |`X-RateLimit-Remaining`|Requests remaining in the current window.| |`X-RateLimit-Reset`|When the window resets, as a Unix timestamp in seconds.| Every response also carries an `X-Request-Id` header. Include it when reporting an issue. ## Handling 429 responses When a key exceeds its limit, the API responds with `429` and error code `RATE_LIMITED`: ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` The response includes a `Retry-After` header with the number of seconds to wait. Back off until then instead of retrying immediately; retries inside the window also count against the limit. ## Device authorization limits The unauthenticated device authorization endpoints are limited per client IP instead of per key: |Endpoint|Limit| |--|--| |`POST /v1/auth/device/code`|10 requests per minute| |`POST /v1/auth/device/token`|30 requests per minute| The token endpoint limit leaves headroom for the standard \~5 second polling interval. ## Other limits |Limit|Behavior when exceeded| |--|--| |Request bodies up to 1 MB|`413` with error code `PAYLOAD_TOO_LARGE`| |50 API keys per organization|`409` with error code `KEY_LIMIT_REACHED`; delete unused keys first. Rolling a key replaces it, so rolling works at the cap.| # List organizations URL: https://inth-docs.vercel.app/docs/rest-api/organizations/list-organizations List organizations ```http GET /v1/organizations ``` Server: `https://api.inth.com` Operation ID: `listOrganizations` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/organizations" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/organizations", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Organizations available to the authenticated principal. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object\[]|required|| |`data[].organizationId`|string|required|| |`data[].organizationSlug`|string|required|| |`data[].organizationName`|string|required|| |`data[].role`|string|required|| Example: default ```json { "success": true, "data": [ { "organizationId": "org_123", "organizationSlug": "acme", "organizationName": "Acme", "role": "owner" } ] } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "array", "items": { "type": "object", "required": [ "organizationId", "organizationSlug", "organizationName", "role" ], "properties": { "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "organizationName": { "type": "string" }, "role": { "type": "string" } } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Create project URL: https://inth-docs.vercel.app/docs/rest-api/projects/create-project Creates a project and provisions its initial consent instance. ```http POST /v1/projects ``` Server: `https://api.inth.com` Operation ID: `createProject` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Request Body required Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`organizationId`|string|required|| |`name`|string|required|Project display name. The initial consent instance inherits it.| |`region`|string|required|| |`trustedOrigins`|string\[]|optional|| |`consent`|object|optional|Optional consent instance configuration applied at creation, so no follow-up request is needed.| |`consent.branding`|"inth" \|"c15t" \|"none"|optional|Consent banner branding. \`none\` requires a plan that includes remove-branding and otherwise fails with 402 before the project is created.| JSON Schema: ```json { "type": "object", "required": [ "organizationId", "name", "region" ], "properties": { "organizationId": { "type": "string", "minLength": 1 }, "name": { "type": "string", "minLength": 1, "description": "Project display name. The initial consent instance inherits it." }, "region": { "type": "string", "minLength": 1 }, "trustedOrigins": { "type": "array", "items": { "type": "string" }, "default": [] }, "consent": { "type": "object", "description": "Optional consent instance configuration applied at creation, so no follow-up request is needed.", "properties": { "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Consent banner branding. `none` requires a plan that includes remove-branding and otherwise fails with 402 before the project is created." } } } } } ``` ## Code Examples ### cURL ```bash curl -X POST "https://api.inth.com/v1/projects" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "organizationId": "org_123", "name": "Website", "region": "us-east-1", "trustedOrigins": [ "example.com", "*.example.com" ], "consent": { "branding": "inth" } }' ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects", { method: "POST", headers: { "Authorization": "Bearer ", "Content-Type": "application/json" }, body: JSON.stringify({ "organizationId": "org_123", "name": "Website", "region": "us-east-1", "trustedOrigins": [ "example.com", "*.example.com" ], "consent": { "branding": "inth" } }), }); const data = await response.json(); ``` ## Responses ### 201 Created project. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.projectId`|string|required|| |`data.projectSlug`|string|required|| |`data.projectName`|string|required|| |`data.description`|string \|null|required|| |`data.organizationId`|string|required|| |`data.organizationSlug`|string|required|| |`data.dashboardURL`|string (uri)|required|| |`data.products`|object|required|| |`data.products.consent`|object \|null|required|| Example: default ```json { "success": true, "data": { "projectId": "prj_123", "projectSlug": "website", "projectName": "Website", "description": null, "organizationId": "org_123", "organizationSlug": "acme", "dashboardURL": "https://inth.com/dashboard/acme/website", "products": { "consent": { "instanceId": "ins_123", "instanceSlug": "website", "instanceName": "Website", "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "inth", "backendURL": "https://website-acme.inth.app/", "dashboardURL": "https://inth.com/dashboard/acme/website/consent/overview", "backendVersion": "v2" } } } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "projectId", "projectSlug", "projectName", "description", "organizationId", "organizationSlug", "dashboardURL", "products" ], "properties": { "projectId": { "type": "string" }, "projectSlug": { "type": "string" }, "projectName": { "type": "string" }, "description": { "oneOf": [ { "type": "string" }, { "type": "null" } ] }, "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "dashboardURL": { "type": "string", "format": "uri" }, "products": { "type": "object", "required": [ "consent" ], "properties": { "consent": { "oneOf": [ { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } }, { "type": "null" } ] } } } } } } } ``` ### 400 Invalid payload, region, or trusted origin. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: invalidPayload ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` Example: invalidRegion ```json { "success": false, "error": { "code": "INVALID_REGION", "message": "Unsupported region" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 409 The request conflicts with the current resource state. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 413 The request body exceeds the 1 MB limit. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Delete project URL: https://inth-docs.vercel.app/docs/rest-api/projects/delete-project Archives the project and linked active consent instances for the authenticated organization. ```http DELETE /v1/projects/{projectId} ``` Server: `https://api.inth.com` Operation ID: `deleteProject` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`projectId`|string|required|Project identifier.| ## Code Examples ### cURL ```bash curl -X DELETE "https://api.inth.com/v1/projects/prj_123" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects/prj_123", { method: "DELETE", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Project was deleted. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.deleted`|boolean|required|| Example: default ```json { "success": true, "data": { "deleted": true } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "deleted" ], "properties": { "deleted": { "type": "boolean" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Get project URL: https://inth-docs.vercel.app/docs/rest-api/projects/get-project Get project ```http GET /v1/projects/{projectId} ``` Server: `https://api.inth.com` Operation ID: `getProject` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`projectId`|string|required|Project identifier.| ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/projects/prj_123" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects/prj_123", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Requested project. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.projectId`|string|required|| |`data.projectSlug`|string|required|| |`data.projectName`|string|required|| |`data.description`|string \|null|required|| |`data.organizationId`|string|required|| |`data.organizationSlug`|string|required|| |`data.dashboardURL`|string (uri)|required|| |`data.products`|object|required|| |`data.products.consent`|object \|null|required|| Example: default ```json { "success": true, "data": { "projectId": "prj_123", "projectSlug": "website", "projectName": "Website", "description": null, "organizationId": "org_123", "organizationSlug": "acme", "dashboardURL": "https://inth.com/dashboard/acme/website", "products": { "consent": { "instanceId": "ins_123", "instanceSlug": "website", "instanceName": "Website", "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "inth", "backendURL": "https://website-acme.inth.app/", "dashboardURL": "https://inth.com/dashboard/acme/website/consent/overview", "backendVersion": "v2" } } } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "projectId", "projectSlug", "projectName", "description", "organizationId", "organizationSlug", "dashboardURL", "products" ], "properties": { "projectId": { "type": "string" }, "projectSlug": { "type": "string" }, "projectName": { "type": "string" }, "description": { "oneOf": [ { "type": "string" }, { "type": "null" } ] }, "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "dashboardURL": { "type": "string", "format": "uri" }, "products": { "type": "object", "required": [ "consent" ], "properties": { "consent": { "oneOf": [ { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } }, { "type": "null" } ] } } } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Get project consent settings URL: https://inth-docs.vercel.app/docs/rest-api/projects/get-project-consent Get project consent settings ```http GET /v1/projects/{projectId}/consent ``` Server: `https://api.inth.com` Operation ID: `getProjectConsent` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`projectId`|string|required|Project identifier.| ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/projects/prj_123/consent" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects/prj_123/consent", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Linked consent instance settings for the project. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.instanceId`|string|required|| |`data.instanceSlug`|string|required|| |`data.instanceName`|string|required|| |`data.trustedOrigins`|string\[]|required|| |`data.branding`|"inth" \|"c15t" \|"none"|required|Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan.| |`data.backendURL`|string \|null|required|| |`data.dashboardURL`|string (uri)|required|| |`data.backendVersion`|string|required|| Example: default ```json { "success": true, "data": { "instanceId": "ins_123", "instanceSlug": "website", "instanceName": "Website", "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "inth", "backendURL": "https://website-acme.inth.app/", "dashboardURL": "https://inth.com/dashboard/acme/website/consent/overview", "backendVersion": "v2" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # List projects URL: https://inth-docs.vercel.app/docs/rest-api/projects/list-projects List projects ```http GET /v1/projects ``` Server: `https://api.inth.com` Operation ID: `listProjects` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Query Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`organizationId`|string|optional|Restrict results to one organization the authenticated principal can access.| |`limit`|integer|required|Page size, between 1 and 100.| |`cursor`|string|optional|Opaque cursor from the previous page’s pagination.nextCursor.| ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/projects?limit=50" \ -H "Authorization: Bearer " ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects?limit=50", { method: "GET", headers: { "Authorization": "Bearer " }, }); const data = await response.json(); ``` ## Responses ### 200 Inth projects for the authenticated principal. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object\[]|required|| |`data[].projectId`|string|required|| |`data[].projectSlug`|string|required|| |`data[].projectName`|string|required|| |`data[].description`|string \|null|required|| |`data[].organizationId`|string|required|| |`data[].organizationSlug`|string|required|| |`data[].dashboardURL`|string (uri)|required|| |`data[].products`|object|required|| |`data[].products.consent`|object \|null|required|| |`pagination`|object|required|| |`pagination.nextCursor`|string \|null|required|| |`pagination.hasMore`|boolean|required|| Example: ```json { "success": true, "data": [ { "projectId": "string", "projectSlug": "string", "projectName": "string", "description": "string", "organizationId": "string", "organizationSlug": "string", "dashboardURL": "https://example.com", "products": { "consent": {} } } ], "pagination": { "nextCursor": "string", "hasMore": true } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data", "pagination" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "array", "items": { "type": "object", "required": [ "projectId", "projectSlug", "projectName", "description", "organizationId", "organizationSlug", "dashboardURL", "products" ], "properties": { "projectId": { "type": "string" }, "projectSlug": { "type": "string" }, "projectName": { "type": "string" }, "description": { "oneOf": [ { "type": "string" }, { "type": "null" } ] }, "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "dashboardURL": { "type": "string", "format": "uri" }, "products": { "type": "object", "required": [ "consent" ], "properties": { "consent": { "oneOf": [ { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } }, { "type": "null" } ] } } } } } }, "pagination": { "type": "object", "required": [ "nextCursor", "hasMore" ], "properties": { "nextCursor": { "oneOf": [ { "type": "string", "description": "Cursor for the next page; null on the last page." }, { "type": "null" } ] }, "hasMore": { "type": "boolean" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 402 The requested operation requires a paid plan. API access (organization API keys) requires the Starter plan or higher; a downgraded organization receives this error until its plan is restored. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "PLAN_REQUIRED", "message": "API access requires the Starter plan or higher" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # List provisioning regions URL: https://inth-docs.vercel.app/docs/rest-api/projects/list-regions List provisioning regions ```http GET /v1/regions ``` Server: `https://api.inth.com` Operation ID: `listRegions` ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/v1/regions" ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/regions", { method: "GET", }); const data = await response.json(); ``` ## Responses ### 200 Regions available for Inth project provisioning. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object\[]|required|| |`data[].id`|string|required|| |`data[].label`|string|required|| Example: default ```json { "success": true, "data": [ { "id": "us-east-1", "label": "US East (N. Virginia)" } ] } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "array", "items": { "type": "object", "required": [ "id", "label" ], "properties": { "id": { "type": "string" }, "label": { "type": "string" } } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Update project URL: https://inth-docs.vercel.app/docs/rest-api/projects/update-project Updates project metadata. Changing projectName also updates the project slug. ```http PATCH /v1/projects/{projectId} ``` Server: `https://api.inth.com` Operation ID: `updateProject` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`projectId`|string|required|Project identifier.| ### Request Body required Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`projectName`|string|optional|Project display name. Updating it also regenerates the project slug.| |`description`|string \|null|optional|| JSON Schema: ```json { "type": "object", "minProperties": 1, "properties": { "projectName": { "type": "string", "minLength": 1, "description": "Project display name. Updating it also regenerates the project slug." }, "description": { "oneOf": [ { "type": "string", "maxLength": 512 }, { "type": "null" } ] } } } ``` ## Code Examples ### cURL ```bash curl -X PATCH "https://api.inth.com/v1/projects/prj_123" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "projectName": "Marketing Website", "description": "Primary marketing website." }' ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects/prj_123", { method: "PATCH", headers: { "Authorization": "Bearer ", "Content-Type": "application/json" }, body: JSON.stringify({ "projectName": "Marketing Website", "description": "Primary marketing website." }), }); const data = await response.json(); ``` ## Responses ### 200 Updated project. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.projectId`|string|required|| |`data.projectSlug`|string|required|| |`data.projectName`|string|required|| |`data.description`|string \|null|required|| |`data.organizationId`|string|required|| |`data.organizationSlug`|string|required|| |`data.dashboardURL`|string (uri)|required|| |`data.products`|object|required|| |`data.products.consent`|object \|null|required|| Example: default ```json { "success": true, "data": { "projectId": "prj_123", "projectSlug": "marketing-website", "projectName": "Marketing Website", "description": "Primary marketing website.", "organizationId": "org_123", "organizationSlug": "acme", "dashboardURL": "https://inth.com/dashboard/acme/website", "products": { "consent": { "instanceId": "ins_123", "instanceSlug": "website", "instanceName": "Website", "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "inth", "backendURL": "https://website-acme.inth.app/", "dashboardURL": "https://inth.com/dashboard/acme/website/consent/overview", "backendVersion": "v2" } } } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "projectId", "projectSlug", "projectName", "description", "organizationId", "organizationSlug", "dashboardURL", "products" ], "properties": { "projectId": { "type": "string" }, "projectSlug": { "type": "string" }, "projectName": { "type": "string" }, "description": { "oneOf": [ { "type": "string" }, { "type": "null" } ] }, "organizationId": { "type": "string" }, "organizationSlug": { "type": "string" }, "dashboardURL": { "type": "string", "format": "uri" }, "products": { "type": "object", "required": [ "consent" ], "properties": { "consent": { "oneOf": [ { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } }, { "type": "null" } ] } } } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 409 The request conflicts with the current resource state. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 413 The request body exceeds the 1 MB limit. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Update project consent settings URL: https://inth-docs.vercel.app/docs/rest-api/projects/update-project-consent Partially updates consent settings on the instance linked to this project. ```http PATCH /v1/projects/{projectId}/consent ``` Server: `https://api.inth.com` Operation ID: `updateProjectConsent` ## Authentication * bearerAuth ### Schemes * bearerAuth: http / bearer - Use an Inth API key or OAuth access token in the Authorization header. ## Request ### Path Parameters |Name|Type|Required|Description| |:--|:--|:--|:--| |`projectId`|string|required|Project identifier.| ### Request Body required Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`trustedOrigins`|string\[]|optional|Origins allowed to call the linked consent instance. Supports \* and wildcard subdomains like \*.example.com.| |`branding`|"inth" \|"c15t" \|"none"|optional|Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan.| JSON Schema: ```json { "type": "object", "minProperties": 1, "properties": { "trustedOrigins": { "type": "array", "items": { "type": "string" }, "description": "Origins allowed to call the linked consent instance. Supports * and wildcard subdomains like *.example.com." }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." } } } ``` ## Code Examples ### cURL ```bash curl -X PATCH "https://api.inth.com/v1/projects/prj_123/consent" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "none" }' ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/v1/projects/prj_123/consent", { method: "PATCH", headers: { "Authorization": "Bearer ", "Content-Type": "application/json" }, body: JSON.stringify({ "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "none" }), }); const data = await response.json(); ``` ## Responses ### 200 Updated linked consent instance settings. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.instanceId`|string|required|| |`data.instanceSlug`|string|required|| |`data.instanceName`|string|required|| |`data.trustedOrigins`|string\[]|required|| |`data.branding`|"inth" \|"c15t" \|"none"|required|Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan.| |`data.backendURL`|string \|null|required|| |`data.dashboardURL`|string (uri)|required|| |`data.backendVersion`|string|required|| Example: default ```json { "success": true, "data": { "instanceId": "ins_123", "instanceSlug": "website", "instanceName": "Website", "trustedOrigins": [ "example.com", "*.example.com" ], "branding": "inth", "backendURL": "https://website-acme.inth.app/", "dashboardURL": "https://inth.com/dashboard/acme/website/consent/overview", "backendVersion": "v2" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "instanceId", "instanceSlug", "instanceName", "trustedOrigins", "branding", "backendURL", "dashboardURL", "backendVersion" ], "properties": { "instanceId": { "type": "string" }, "instanceSlug": { "type": "string" }, "instanceName": { "type": "string" }, "trustedOrigins": { "type": "array", "items": { "type": "string" } }, "branding": { "type": "string", "enum": [ "inth", "c15t", "none" ], "description": "Branding shown in the consent banner. Removing branding with 'none' requires an eligible paid plan." }, "backendURL": { "oneOf": [ { "type": "string", "format": "uri" }, { "type": "null" } ] }, "dashboardURL": { "type": "string", "format": "uri" }, "backendVersion": { "type": "string" } } } } } ``` ### 400 The request payload or parameters are invalid. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INVALID_PAYLOAD", "message": "Invalid request payload", "details": [ { "code": "too_small", "message": "Too small: expected string to have >=1 characters", "path": [ "name" ] } ] } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 401 Authentication is missing, invalid, or expired. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "UNAUTHORIZED", "message": "Authentication required" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 403 The authenticated principal cannot access the resource. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 404 The requested resource was not found. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 409 The request conflicts with the current resource state. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 413 The request body exceeds the 1 MB limit. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: ```json { "success": true, "error": { "code": "UNAUTHORIZED", "message": "string", "details": {} } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 429 The rate limit was exceeded. API key limits are set by plan tier (Starter 600/min, Pro 1500/min, Enterprise 3000/min). Check the Retry-After header before retrying. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "RATE_LIMITED", "message": "API key rate limit exceeded" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ### 500 An unexpected internal error occurred. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Internal server error" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Health check URL: https://inth-docs.vercel.app/docs/rest-api/system/get-health Health check ```http GET /health ``` Server: `https://api.inth.com` Operation ID: `getHealth` ## Code Examples ### cURL ```bash curl -X GET "https://api.inth.com/health" ``` ### JavaScript ```ts const response = await fetch("https://api.inth.com/health", { method: "GET", }); const data = await response.json(); ``` ## Responses ### 200 API service is healthy. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`data`|object|required|| |`data.ok`|boolean|required|| |`data.database`|object|required|| |`data.database.ok`|boolean|required|| Example: default ```json { "success": true, "data": { "ok": true, "database": { "ok": true } } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "data" ], "properties": { "success": { "type": "boolean", "const": true }, "data": { "type": "object", "required": [ "ok", "database" ], "properties": { "ok": { "type": "boolean" }, "database": { "type": "object", "required": [ "ok" ], "properties": { "ok": { "type": "boolean" } } } } } } } ``` ### 503 Dashboard database health check failed. Content type: application/json |Property|Type|Required|Description| |:--|:--|:--|:--| |`success`|boolean|required|| |`error`|object|required|| |`error.code`|"UNAUTHORIZED" \|"FORBIDDEN" \|"INSTANCE\_LIMIT\_REACHED" \|"PLAN\_LIMIT\_REACHED" \|"PLAN\_REQUIRED" \|"INVALID\_ORIGIN" \|"INVALID\_REGION" \|"INVALID\_PAYLOAD" \|"NOT\_FOUND" \|"CONFLICT" \|"KEY\_LIMIT\_REACHED" \|"PAYLOAD\_TOO\_LARGE" \|"RATE\_LIMITED" \|"SERVICE\_UNAVAILABLE" \|"INTERNAL\_ERROR"|required|| |`error.message`|string|required|| |`error.details`|unknown|optional|Optional structured error details.| Example: default ```json { "success": false, "error": { "code": "SERVICE_UNAVAILABLE", "message": "Dashboard database health check failed" } } ``` JSON Schema: ```json { "type": "object", "required": [ "success", "error" ], "properties": { "success": { "type": "boolean", "const": false }, "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "enum": [ "UNAUTHORIZED", "FORBIDDEN", "INSTANCE_LIMIT_REACHED", "PLAN_LIMIT_REACHED", "PLAN_REQUIRED", "INVALID_ORIGIN", "INVALID_REGION", "INVALID_PAYLOAD", "NOT_FOUND", "CONFLICT", "KEY_LIMIT_REACHED", "PAYLOAD_TOO_LARGE", "RATE_LIMITED", "SERVICE_UNAVAILABLE", "INTERNAL_ERROR" ] }, "message": { "type": "string" }, "details": { "description": "Optional structured error details." } } } } } ``` ## Related * [REST API overview](/docs/rest-api): Every operation in this API. # Website Audit URL: https://inth-docs.vercel.app/docs/website-audit Scan a production website for vendors, cookies, and runtime evidence. Inth Website Audit visits your production website and records privacy-relevant runtime behavior. It identifies vendors and cookies, observes scripts, frames, network destinations, and browser storage keys, preserves supporting technical evidence, and highlights changes between comparable scans. > ℹ️ **Info:** **Limited beta** > Inth Website Audit is currently available only to selected organizations. If Website Audit does not appear in the dashboard, your organization does not currently have access. Inth records cookie attributes and storage key names, not their stored values. You do not need to install a snippet on the website. Use Website Audit to answer questions such as: * Which vendors and third-party domains were observed? * Which first-party and third-party cookies were set? * Which detections could not be matched to a known vendor? * Which vendors are new or no longer detected since a comparable scan? * Which pages and scan conditions completed successfully? Website Audit is a point-in-time observation of the pages it can reach. It is not proof that an unobserved vendor, cookie, or behavior does not exist. ## Before you start You need an Inth project and the full public URL of the production website. The site must be reachable without signing in. Public policy pages are optional but recommended. Add pages such as your privacy policy, cookie policy, terms, or subprocessor list so the audit can preserve them as policy evidence. ## Add a website 1. In the Inth dashboard, open **Audit**. 2. Open the project that owns the website. 3. Under **Websites**, select **Add website**. 4. Enter the production origin, including `https://`. 5. Add any public policy pages. 6. Choose which pages to scan and save the website. Each website belongs to a project, so its runtime evidence can be reviewed alongside the related repository and policy context. Inth saves the website origin rather than a single page path. Use URL rules to include or prioritize particular pages. ## Choose pages to scan Website Audit supports four crawl modes: * **Sitemap and linked pages** provides the broadest coverage and is the best default for most sites. * **Linked pages only** is useful when the sitemap is missing or out of date. * **Sitemap only** is faster but cannot discover pages omitted from the sitemap. * **Only the URLs I list** scans only the URLs configured in the website's URL rules. You can refine a crawl with URL rules: * **Start from** seeds the crawl with important pages. * **Limit to** prevents the audit from leaving selected paths. * **Never scan** excludes sensitive or irrelevant paths such as `/admin`. * **Scan first** prioritizes pages that should be visited before the page limit is reached. Rules can only target the website's own origin. A page limit can still prevent a listed URL from being visited, so check the completed coverage in every report. ## Verify the domain If Inth asks you to verify ownership, open **Domain verification** for the website. Depending on your DNS provider, you can: * use the available one-click connection * add the displayed DNS TXT record * serve the verification value from the displayed `/.well-known/inth-verify.txt` URL After publishing the record or file, select **Check verification**. Keep the verification record in place because Inth rechecks it periodically. The first manual scan may be available before verification. Verify the domain to continue running audits when verification is required. ## Configure policy and vendor context In the website's settings, keep policy-page URLs current and add URL rules when the default crawl is too broad or too narrow. You can also add affiliated domains that your organization owns. Without that context, requests to your own secondary domains can appear as unidentified or third-party vendor evidence. ## Run an audit 1. Open the project Audit page. 2. Find the website and select **Run audit**. 3. Follow the active run from **Audit → History**. 4. Open the completed run to review its results. A Website Audit uses Inth Credits. Credits are reserved when the audit starts. If the balance is too low, the dashboard offers a top-up before retrying the same audit. Only one audit can run for a website at a time. Crawl breadth, site size, and site performance affect how long the audit takes. Credits reserved for a failed or cancelled audit are released. ## Review the results The report has four views: * **Overview** shows coverage, unidentified detections, and vendor changes when a comparable scan exists. * **Vendors** lists identified vendors, their categories, where they were observed, and supporting evidence. * **Cookies** separates first-party and third-party cookies and links them to known vendors where possible. * **Review** contains detections that Inth could not confidently attribute to a vendor. Open **Technical evidence** when you need the supporting page, request, script, cookie, or storage details. Vendor changes are shown only when a prior scan has comparable configuration and completed coverage. Incomplete, blocked, page-limited, or truncated coverage must not be treated as proof that a vendor or cookie is absent. ## Coverage and limitations Website Audit scans public, same-origin pages that its browser can reach. Authentication, bot protection, navigation failures, crawl limits, and slow pages can reduce coverage. The current audit observes the site's default page state. It does not select accept or reject in a consent banner, compare several consent choices, or prove that consent enforcement works in every region. Treat the report as runtime evidence for review, not as a compliance certification.