Stellate Private API
This API is not intended for public consumption.
We share this documentation with you to allow you to better integrate with Stellate systems. However, this API is not meant for wider consumption and we ask that you do not share this documentation outside of your team.
The API is avialable at https://api.stellate.co/api
.
For authorization, you will need to provide a valid Access Token via the stellate-token
header. You can create new tokens on your Dashboard at https://stellate.co/app/settings/access-tokens .
Those access tokens are scoped to your user, not a specific organization. Any request using one of your tokens will have the same permissions you have, including access to all organizations and services you have on Stellate.
List all organizations for a user
This function will fetch all organizations relating to a user token, we will use this to write our service to a specific organization.
const token = '<your-token>'
const apiUrl = 'https://api.stellate.co/api'
async function listOrganizations() {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
query {
user {
organizations {
id
name
slug
}
}
}
`,
}),
})
const result = await response.json()
return result.data.user.organizations
}
List all services for a specific organization
async function listServices(slug) {
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
query ($slug: String!) {
organization(slug: $slug) {
name
services(first: 10) {
edges {
node {
id
name
## This config.input is the raw config we have written to
## our GraphQL API, used to e.g. reproduce the raw YAML
## configuration file
config {
input
}
}
}
}
}
}
`,
variables: { slug },
}),
})
const result = await response.json()
return result.data.organization.apps
}
Service configuration
See Configuration File for more information on each of the configuration items.
const backendURL = '<your_backend_url>'
const config = {
// The name to give to our service in stellate. This needs to be unique,
// otherwhise you will get an error back
name: 'node-write-test',
originUrl: backendURL,
// You can fill in a schema here to fetch the introspection from
// or pass in the introspection/schema yourself
schema: backendUrl,
ignoreOriginCacheControl: true,
enablePlayground: true,
injectHeaders: true,
headers: {
'something-to-inject': '1',
},
keyFields: {
types: {
// If you have types that aren't identified by id or _id
// you can fill them in here, this is the key we will use for
// purging/...
YourType: ['specialKey'],
},
},
scopes: {
// Scopes are a way to create separate cache buckets
// for instance a `query { user }` that is based on
// the auth-token might be worth scoping.
// This also makes it so that people can't access others
// resources as we don't perform the authorization logic
// your back-end does
AUTHENTICATED: 'header:Authorization',
},
// If you have any alternative typenames like query refers to RootQuery fill them in here
rootTypeNames: { query: 'Query', mutation: 'Mutaiton' },
rules: [
{
description: 'Cache all queries',
maxAge: 600,
swr: 900,
types: ['Query'],
},
{
description: 'Put users in a separate bucket',
maxAge: 600,
swr: 900,
scope: 'AUTHENTICATED',
types: ['User'],
},
],
// When we see these headers we will automatically bypass the cache for you
// this can come in handy for preview-urls, ...
bypassCacheHeaders: [{ name: 'x-preview-token' }],
}
Some API calls require schema information. You can either provide a local schema you have available, or fetch it via Introspection.
import fetch from 'node-fetch'
import { getIntrospectionQuery } from 'graphql'
const backendURL = 'https://trygql.formidable.dev/graphql/basic-pokedex'
const introspectionResponse = await fetch(originUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: introspectionQuery,
}),
})
const { data: schema } = await introspectionResponse.json()
Create a new service
This method is used to create a new service in a given organization (identified via the orgId
parameter).
const token = '';
const apiUrl = 'https://api.stellate.co/api'
const schema = ''
// See above for more information about the `config` variable
const config = { ... }
async function createApp(orgId, schema) {
const result = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
mutation (
$input: Input!
$schema: IntrospectionQuery
$organizationId: String!
) {
createAppCli(
input: $input
schema: $schema
organizationId: $organizationId
) {
id
config {
input
}
}
}
`,
variables: {
input: config,
schema: schema,
organizationId: orgId
}
})
})
return await result.json()
}
Update an existing service
This method is used to update the configuration of an existing service
const token = '';
const apiUrl = 'https://api.stellate.co/api'
const schema = ''
// See above for more information about the `config` variable
const config = { ... }
async function pushAppConfig(schema) {
const result = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
mutation (
$input: Input!
$appName: String!
$schema: IntrospectionQuery
) {
pushAppConfig(
input: $input
appName: $appName
schema: $schema
## this will confirm before any configuration items is deleted
allowDeletion: true
)
}
`,
variables: {
input: config,
schema: schema,
appName: config.name,
}
})
})
}
Delete a service
To delete an existing service, use the following mutation.
const token = ''
const apiUrl = 'https://api.stellate.co/api'
async function deleteApp() {
const result = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
mutation ($appName: ServiceName) {
deleteApp(name: $appName)
}
`,
variables: {
appName: config.name,
},
}),
})
}
Add a custom domain to an existing service
To add a custom domain to an existing service, make sure the DNS records are provisioned and point at ecp.map.fastly.net
. Once DNS is properly configured, use the following mutation.
const token = ''
const apiUrl = 'https://api.stellate.co/api'
async function deleteApp() {
const result = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'graphcdn-token': token,
},
body: JSON.stringify({
query: /* GraphQL */ `
mutation ($appName: ServiceName!, $domain: String!) {
addCustomDomain(appName: $serviceName, domain: $domain) {
id
customDomain
isCustomDomainVerified
customDomainCnameValidation
customDomainStatus
customDomainError
}
}
`,
variables: {
appName: config.name,
domain: domain,
},
}),
})
}