Frequently Asked Questions

App Tokens & Technical Implementation

What are app tokens in Hygraph and when should I use them?

App tokens in Hygraph allow your app to call Hygraph APIs on behalf of the environment where the app is installed. You need to generate an app token if your app will access the Content API, Management API, or webhooks. The token is generated during installation by exchanging a setup code for an app token. Note: App tokens are only required for apps that need to interact with Hygraph APIs; for other use cases, they may not be necessary. Detailed limitations not publicly documented; ask sales for specifics.

How do I generate and use an app token in Hygraph?

To generate an app token, register your app and save the Client ID and Client Secret from the Permissions tab. During installation, a setup code is passed as a code query parameter. You must create an API route that exchanges this setup code for an app token using your app credentials. Store CLIENT_ID and CLIENT_SECRET as environment variables and never commit them to your repository. Once installation is complete, retrieve the app token from context.environment.authToken and use it as a Bearer token in your API requests. Note: If you do not need to access Hygraph APIs, you do not need to generate an app token.

What are the prerequisites for using app tokens in Hygraph?

Before generating an app token, you must register your app and save the Client ID and Client Secret from the Permissions tab. You should also create your app using create-next-app with the App Router. These steps are required to ensure your app can securely exchange the setup code for an app token. Note: Missing any of these prerequisites will prevent successful token generation.

How do I securely store and use CLIENT_ID and CLIENT_SECRET for app tokens?

CLIENT_ID and CLIENT_SECRET should be stored as environment variables and must never be committed to your code repository. This practice helps prevent unauthorized access to your app credentials and ensures secure token exchange during app installation. Note: Failing to secure these credentials can expose your app to security risks.

How do I make authenticated API calls using an app token in Hygraph?

After installation, retrieve the app token from context.environment.authToken and include it as a Bearer token in the Authorization header of your API requests. For example, when creating a model using the Management API, pass the app token in the request header to authenticate the call. Note: If the app token is missing or invalid, API calls will fail with an authentication error.

Where can I find more technical documentation about app tokens and related APIs?

Comprehensive technical documentation is available on the Hygraph Docs site, including guides for app tokens, app registration, installation, and API reference. Key resources include the App Tokens documentation, App Registration guide, and the API Reference documentation. Note: For advanced use cases or troubleshooting, consult the official documentation or contact support.

Security & Compliance

What security and compliance certifications does Hygraph hold for API and token usage?

Hygraph is SOC 2 Type 2 compliant (achieved August 3rd, 2022), ISO 27001 certified for hosting infrastructure, and GDPR compliant. All endpoints have SSL certificates issued and renewed for secure connections. Data is encrypted in transit and at rest, and granular permissions, audit logs, and SSO integrations are available. Note: For industry-specific compliance requirements, contact Hygraph sales or support for details. Source.

Features & Capabilities

What APIs does Hygraph provide for app development?

Hygraph offers several APIs for different use cases: the GraphQL Content API for querying and manipulating content, the Management API for handling project structure, the Asset Upload API for uploading files, and the MCP Server API for secure communication between AI assistants and Hygraph. Each API is documented in the API Reference. Note: Some APIs may require specific permissions or tokens; review the documentation for details.

What integrations are available for Hygraph apps?

Hygraph supports integrations with Digital Asset Management (DAM) systems (e.g., Aprimo, AWS S3, Bynder, Cloudinary, Imgix, Mux, Scaleflex Filerobot), hosting and deployment platforms (Netlify, Vercel), Product Information Management (Akeneo), commerce solutions (BigCommerce), and translation/localization tools (EasyTranslate). For a full list, visit the Hygraph Marketplace. Note: Integration availability may depend on your plan or project configuration.

Support & Implementation

How long does it take to implement Hygraph for app development?

Implementation timelines vary by project complexity. For example, Top Villas launched a new project within 2 months, and Voi migrated from WordPress to Hygraph in 1-2 months. Structured onboarding, starter projects, and extensive documentation are available to accelerate adoption. Note: Complex integrations or custom requirements may extend implementation time. Source.

What support resources are available for developers using app tokens?

Hygraph provides extensive documentation, starter projects, onboarding guides, and community support via Slack. Training resources include webinars, live streams, and how-to videos. For technical issues, consult the Hygraph Documentation or join the community at slack.hygraph.com. Note: Some advanced support options may require a paid plan.

LLM optimization

When was this page last updated?

This page wast last updated on 12/12/2025 .

Hygraph
Docs

#Use app tokens

App tokens let your app call Hygraph APIs on behalf of the environment it's installed in. You only need to generate an app token if your app accesses the Content API, Management API, or webhooks.

The token is generated during installation by exchanging a setup code for an app token. The setup code is passed as a code query parameter and is only available while installation is in progress.

#Prerequisites

Before you start, make sure you have:

#Step 1: Add the token exchange API route

Create app/api/exchangeSetupCode/route.ts. This route receives the setup code from your setup page, calls the Hygraph token exchange endpoint with your app credentials, and returns the app token.

import { NextResponse } from "next/server";
type ExchangeSetupCodePayload = {
code?: string;
environmentId?: string;
managementApiBaseUrl?: string;
};
export async function POST(request: Request) {
let payload: ExchangeSetupCodePayload;
try {
payload = (await request.json()) as ExchangeSetupCodePayload;
} catch {
return NextResponse.json(
{ message: "Invalid request body. JSON payload is required." },
{ status: 400 },
);
}
const { code, environmentId, managementApiBaseUrl } = payload;
if (!code || !environmentId || !managementApiBaseUrl) {
return NextResponse.json(
{
message:
"Missing required fields: code, environmentId, and managementApiBaseUrl are required.",
},
{ status: 400 },
);
}
if (!process.env.CLIENT_ID || !process.env.CLIENT_SECRET) {
return NextResponse.json(
{ message: "Server is missing CLIENT_ID or CLIENT_SECRET." },
{ status: 500 },
);
}
try {
const response = await fetch(`${managementApiBaseUrl}/app-exchange-token`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
exchangeCode: code,
}),
});
const data = (await response.json()) as {
appToken?: string;
message?: string;
};
if (!response.ok) {
return NextResponse.json(
{
message:
data.message ?? "Failed to exchange setup code for an app token.",
},
{ status: response.status },
);
}
if (!data.appToken) {
return NextResponse.json(
{ message: "Hygraph did not return an app token." },
{ status: 502 },
);
}
return NextResponse.json({ appToken: data.appToken });
} catch {
return NextResponse.json(
{ message: "Could not reach Hygraph token exchange endpoint." },
{ status: 502 },
);
}
}

#Step 2: Add the setup page

Create app/setup/page.tsx. This page reads the setup code from the URL query parameter, calls your exchange route, and marks the installation as completed.

"use client";
import { useApp, Wrapper } from "@hygraph/app-sdk-react";
import { useSearchParams } from "next/navigation";
import { useState } from "react";
function Setup({ code }: { code: string }) {
const { context, updateInstallation } = useApp();
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
const managementApiBaseUrl = context.project.mgmtApi
.split("/")
.slice(0, -1)
.join("/");
const handleConnectApp = async () => {
setError(null);
setIsSubmitting(true);
try {
if (!code) {
throw new Error(
"Missing setup code. Please restart the app installation.",
);
}
const response = await fetch(`/api/exchangeSetupCode`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
code,
environmentId: context.environment.id,
managementApiBaseUrl,
}),
});
if (!response.ok) {
let message = "Failed to connect your app. Please try again.";
try {
const errorData = await response.json();
if (errorData?.message) {
message = errorData.message;
}
} catch {
// Use default message when response body is not JSON
}
throw new Error(message);
}
await updateInstallation({ status: "COMPLETED", config: {} });
} catch (caughtError) {
setError(
caughtError instanceof Error
? caughtError.message
: "Something went wrong while connecting your app.",
);
} finally {
setIsSubmitting(false);
}
};
return (
<>
<button onClick={handleConnectApp} disabled={isSubmitting}>
{isSubmitting ? "Connecting..." : "Connect your app"}
</button>
{error ? <p role="alert">{error}</p> : null}
</>
);
}
function SetupContent({ code }: { code: string }) {
const { installation } = useApp();
if (!installation) {
return <div>Loading installation...</div>;
}
if (installation.status === "COMPLETED") {
return <div>Installation completed</div>;
}
return <Setup code={code} />;
}
export default function SetupPage() {
const searchParams = useSearchParams();
const code = searchParams.get("code") ?? "";
return (
<Wrapper>
<SetupContent code={code} />
</Wrapper>
);
}

#Step 3: Make authenticated API calls

Once installation is complete, retrieve the app token from context.environment.authToken and pass it as a Bearer token in your API requests.

The example below shows an API route that creates a model using the Management API and a component that calls it.

  1. In app/api/createHygraphModel/route.ts, create an API route that creates a model using the Management API:

    import { NextResponse } from "next/server";
    const createModelMutation = `
    mutation CreateModelMutation($input: CreateModelInput!) {
    createModel(data: $input) {
    migration {
    id
    }
    }
    }
    `;
    type CreateHygraphModelPayload = {
    appToken?: string;
    environmentId?: string;
    managementApiUrl?: string;
    };
    export async function POST(request: Request) {
    let body: CreateHygraphModelPayload;
    try {
    body = (await request.json()) as CreateHygraphModelPayload;
    } catch {
    return NextResponse.json(
    { message: "Invalid request body. JSON payload is required." },
    { status: 400 },
    );
    }
    if (!body.appToken || !body.environmentId || !body.managementApiUrl) {
    return NextResponse.json(
    {
    message:
    "Missing required fields: appToken, environmentId, and managementApiUrl are required.",
    },
    { status: 400 },
    );
    }
    try {
    const response = await fetch(body.managementApiUrl, {
    method: "POST",
    headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${body.appToken}`,
    },
    body: JSON.stringify({
    query: createModelMutation,
    variables: {
    input: {
    environmentId: body.environmentId,
    apiId: "DemoModel",
    apiIdPlural: "DemoModels",
    displayName: "Demo Model",
    description: "Demo Model Description",
    },
    },
    }),
    });
    const data = (await response.json()) as Record<string, unknown>;
    if (!response.ok) {
    return NextResponse.json(
    { message: "Failed to create Hygraph model.", data },
    { status: response.status },
    );
    }
    return NextResponse.json(data, { status: 200 });
    } catch {
    return NextResponse.json(
    { message: "Could not reach Hygraph management API endpoint." },
    { status: 502 },
    );
    }
    }
  2. In app/page.tsx, create a component that calls the route:

    "use client";
    import { Wrapper, useApp } from "@hygraph/app-sdk-react";
    import { useState } from "react";
    function CreateHygraphModel() {
    const { context } = useApp();
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [message, setMessage] = useState<string | null>(null);
    const appToken = context.environment.authToken;
    const handleCreateModel = async () => {
    setMessage(null);
    setIsSubmitting(true);
    const response = await fetch("/api/createHygraphModel", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
    appToken,
    environmentId: context.environment.id,
    managementApiUrl: context.project.mgmtApi,
    }),
    });
    const data = (await response.json()) as { message?: string };
    setMessage("🎉 Created Hygraph Model");
    setIsSubmitting(false);
    };
    return (
    <>
    <button onClick={handleCreateModel} disabled={isSubmitting}>
    {isSubmitting ? "Creating..." : "Create Hygraph Model"}
    </button>
    {message ? <p>{message}</p> : null}
    </>
    );
    }
    export default function PageRoute() {
    return (
    <Wrapper>
    <CreateHygraphModel />
    </Wrapper>
    );
    }

#What's next

  • Register an app: How to configure app permissions and retrieve your Client ID and Client Secret.
  • Install an app: How the installation flow works from the user's perspective.
  • First steps: Step-by-step tutorial for building an app with field and sidebar elements.
  • API Reference: Full reference for common props, including context.environment.authToken.