This quickstart uses a server-side API key. Create and protect one with the authentication guide .
Protect the key in your shell
Keep the value out of shell history. Use a local secret manager or a temporary protected environment variable when possible. export BILY_API_KEY = "<your-key>"
Confirm your access
curl --fail-with-body \
--url https://app.bily.ai/api/customer/v1/context \
--header "x-api-key: $BILY_API_KEY "
The response groups every visible store under its organization: {
"user" : {
"id" : "usr_01J8W6T2QF4M7Z9A3K5N1P0R8S" ,
"email" : "developer@example.com" ,
"emailVerified" : true ,
"name" : "Bily Developer" ,
"image" : null
},
"organizations" : [
{
"id" : "org_01J8W7T9G3E6ZQ4M2K5N8P1R0S" ,
"name" : "Example organization" ,
"slug" : "example-organization" ,
"createdAt" : "2026-07-01T00:00:00.000Z" ,
"stores" : [
{
"id" : "store_01J8W8D5GSPN3XQYF4K2A6M7RT" ,
"url" : "store.example.com" ,
"type" : "shopify" ,
"currency" : "USD" ,
"createdAt" : "2026-07-01T00:00:00.000Z" ,
"updatedAt" : "2026-07-14T00:00:00.000Z"
}
]
}
]
}
A standard settings-generated key is already store-scoped. Do not add an organization parameter. Copy the exact organizations[].stores[].url value into store-scoped endpoints.
Read the store profile
curl --fail-with-body \
--url https://app.bily.ai/api/customer/v1/store-data/store.example.com \
--header "x-api-key: $BILY_API_KEY "
If an older key from Settings > MCP returns 403 and requires store scope, select the intended store and create a replacement scoped key.
Choose an organization when required
Use organizationId only when the authenticated identity can access multiple organizations and the workload deliberately selects one:
curl --fail-with-body --get \
--url https://app.bily.ai/api/customer/v1/context \
--header "x-api-key: $BILY_API_KEY " \
--data-urlencode "organizationId=org_01J8W7T9G3E6ZQ4M2K5N8P1R0S"
The organization must remain inside the credential’s allowed scope. Omit this parameter for store-scoped keys.
Reuse a safe JavaScript client
const apiKey = process . env . BILY_API_KEY ;
if ( ! apiKey ) {
throw new Error ( "BILY_API_KEY is required" );
}
async function bilyRequest < T >( path : string , init : RequestInit = {}) : Promise < T > {
const response = await fetch ( `https://app.bily.ai/api/customer/v1 ${ path } ` , {
... init ,
headers: {
accept: "application/json" ,
"x-api-key" : apiKey ,
... init . headers ,
},
});
if ( ! response . ok ) {
const requestId = response . headers . get ( "x-request-id" );
const detail = await response . text ();
throw new Error ( `Bily request failed ( ${ response . status } , request ${ requestId } ): ${ detail } ` );
}
return response . json () as Promise < T >;
}
const context = await bilyRequest <{
user : { id : string ; email : string ; name : string };
organizations : Array <{
id : string ;
name : string ;
stores : Array <{ id : string ; url : string }>;
}>;
}>( "/context" );
const store = context . organizations [ 0 ]?. stores [ 0 ];
if ( ! store ) {
throw new Error ( "No accessible Bily store found" );
}
const profile = await bilyRequest < Record < string , unknown >>(
`/store-data/ ${ encodeURIComponent ( store . url ) } ` ,
);
console . log ({ user: context . user , store , profile });
Browse all endpoints Open the generated endpoint reference, including GET /context, in the Bily API tab.