#terminal api

v1.0.3

the terminal api gives you access to the same api that powers the award winning terminal ssh shop.

#servers

  • https://api.dev.terminal.shop (Dev Sandbox)
  • https://api.terminal.shop (Production)

#getting started

The Terminal API allows you to interact with the Terminal e-commerce platform. You can use it to order your own coffee however you like (cron job, neovim plugin, github action, etc.), or even create apps that allow others to authenticate through OAuth 2.0 and purchase their coffee.

There are two environments for the Terminal API: the dev sandbox, and production. The dev sandbox allows you to test out the API without creating real charges against a credit card (use the Stripe test card: 4242424242424242), and, obviously, we won't be fulfilling any orders in dev. The production environment is the real deal, and we will be fulfilling orders against real credit cards, so be careful! Or don't, we'll gladly take your money and send you coffee, just no infinite loops, pls.

We don't know what you might do with it, but our OpenAPI 3.1 specification is available here.

#authentication

There are two ways to authenticate with the Terminal API: using a personal access token, or using an OAuth 2.0 client ID and secret.

The personal access token is a simple secret (string) that can be passed as a bearer token in the Authorization header. All API actions will be performed on behalf of the user associated with the token (you!). You can manage your personal access tokens in the Account page of the SSH shop:

ssh dev.terminal.shop -t tokens  # dev sandbox
ssh terminal.shop -t tokens      # production

The OAuth 2.0 client ID and secret are used to authenticate with the API on behalf of another user. Like personal access tokens, you can create and manage OAuth 2.0 apps in the Account page of the SSH shop:

ssh dev.terminal.shop -t apps  # dev sandbox
ssh terminal.shop -t apps      # production

You can find OAuth 2.0 configuration info here for the dev sandbox, and here for production. Note: we don't do anything with `scope`, so pass anything you like just remember that we probably log them and will post any funny values on the internet.

#client sdks

If you don't prefer making HTTP requests yourself, you can use one of our many client SDKs to interact with the Terminal API.

note: Our SDKs are created by the talented team at Stainless, they're awesome and you should check them out.

#Product

GET

/product

list products

public

GET

/product/{id}

get product

public

get

/product

public

List all products for sale in the Terminal shop.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const products = await client.product.list();

  console.log(products.data);
}

main();
get

/product/{id}

public

Get a product by ID from the Terminal shop.

#parameters

idstringID of the product to get.
example: `prd_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const product = await client.product.get('prd_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(product.data);
}

main();

#Profile

GET

/profile

get profile

PUT

/profile

update profile

get

/profile

Get the current user's profile.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.profile.me();

  console.log(response.data);
}

main();
put

/profile

Update the current user's profile.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const profile = await client.profile.update({ email: 'john@example.com', name: 'John Doe' });

  console.log(profile.data);
}

main();

#Address

GET

/address

get addresses

GET

/address/{id}

get address

POST

/address

create address

DELETE

/address/{id}

delete address

get

/address

Get the shipping addresses associated with the current user.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const addresses = await client.address.list();

  console.log(addresses.data);
}

main();
get

/address/{id}

Get the shipping address with the given ID.

#parameters

idstringID of the shipping address to get.
example: `shp_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const address = await client.address.get('shp_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(address.data);
}

main();
post

/address

Create and add a shipping address to the current user.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const address = await client.address.create({
    city: 'Anytown',
    country: 'US',
    name: 'John Doe',
    street1: '123 Main St',
    zip: '12345',
  });

  console.log(address.data);
}

main();
delete

/address/{id}

Delete a shipping address from the current user.

#parameters

idstringID of the shipping address to delete.
example: `shp_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const address = await client.address.delete('shp_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(address.data);
}

main();

#Card

GET

/card

list cards

GET

/card/{id}

get card

POST

/card

create card

POST

/card/collect

collect card

DELETE

/card/{id}

delete card

get

/card

List the credit cards associated with the current user.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const cards = await client.card.list();

  console.log(cards.data);
}

main();
get

/card/{id}

Get a credit card by ID associated with the current user.

#parameters

idstringID of the card to get.
example: `crd_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const card = await client.card.get('crd_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(card.data);
}

main();
post

/card

Attach a credit card (tokenized via Stripe) to the current user.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const card = await client.card.create({ token: 'tok_1N3T00LkdIwHu7ixt44h1F8k' });

  console.log(card.data);
}

main();
post

/card/collect

Create a temporary URL for collecting credit card information for the current user.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.card.collect();

  console.log(response.data);
}

main();
delete

/card/{id}

Delete a credit card associated with the current user.

#parameters

idstringID of the card to delete.
example: `crd_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const card = await client.card.delete('crd_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(card.data);
}

main();

#Cart

GET

/cart

get cart

PUT

/cart/item

add item

PUT

/cart/address

set address

PUT

/cart/card

set card

POST

/cart/convert

convert to order

DELETE

/cart

clear cart

get

/cart

Get the current user's cart.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const cart = await client.cart.get();

  console.log(cart.data);
}

main();
put

/cart/item

Add an item to the current user's cart.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.cart.setItem({
    productVariantID: 'var_XXXXXXXXXXXXXXXXXXXXXXXXX',
    quantity: 2,
  });

  console.log(response.data);
}

main();
put

/cart/address

Set the shipping address for the current user's cart.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.cart.setAddress({ addressID: 'shp_XXXXXXXXXXXXXXXXXXXXXXXXX' });

  console.log(response.data);
}

main();
put

/cart/card

Set the credit card for the current user's cart.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.cart.setCard({ cardID: 'crd_XXXXXXXXXXXXXXXXXXXXXXXXX' });

  console.log(response.data);
}

main();
post

/cart/convert

Convert the current user's cart to an order.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.cart.convert();

  console.log(response.data);
}

main();
delete

/cart

Clear the current user's cart.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.cart.clear();

  console.log(response.data);
}

main();

#Order

GET

/order

list orders

GET

/order/{id}

get order

POST

/order

create order

get

/order

List the orders associated with the current user.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const orders = await client.order.list();

  console.log(orders.data);
}

main();
get

/order/{id}

Get the order with the given ID.

#parameters

idstringID of the order to get.
example: `ord_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const order = await client.order.get('ord_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(order.data);
}

main();
post

/order

Create an order without a cart. The order will be placed immediately.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const order = await client.order.create({
    addressID: 'shp_XXXXXXXXXXXXXXXXXXXXXXXXX',
    cardID: 'crd_XXXXXXXXXXXXXXXXXXXXXXXXX',
    variants: { var_XXXXXXXXXXXXXXXXXXXXXXXXX: 1 },
  });

  console.log(order.data);
}

main();

#Subscription

GET

/subscription

list subscriptions

GET

/subscription/{id}

get subscription

PUT

/subscription/{id}

update subscription

POST

/subscription

subscribe

DELETE

/subscription/{id}

cancel

get

/subscription

List the subscriptions associated with the current user.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const subscriptions = await client.subscription.list();

  console.log(subscriptions.data);
}

main();
get

/subscription/{id}

Get the subscription with the given ID.

#parameters

idstringID of the subscription to get.
example: `sub_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const subscription = await client.subscription.get('sub_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(subscription.data);
}

main();
put

/subscription/{id}

Update card, address, or interval for an existing subscription.

#parameters

idstringID of the subscription to update.
example: `sub_XXXXXXXXXXXXXXXXXXXXXXXXX`

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const subscription = await client.subscription.update('sub_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(subscription.data);
}

main();
post

/subscription

Create a subscription for the current user.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const subscription = await client.subscription.create({
    id: 'sub_XXXXXXXXXXXXXXXXXXXXXXXXX',
    addressID: 'shp_XXXXXXXXXXXXXXXXXXXXXXXXX',
    cardID: 'crd_XXXXXXXXXXXXXXXXXXXXXXXXX',
    created: '2024-06-29T19:36:19.000Z',
    price: 2200,
    productVariantID: 'var_XXXXXXXXXXXXXXXXXXXXXXXXX',
    quantity: 1,
  });

  console.log(subscription.data);
}

main();
delete

/subscription/{id}

Cancel a subscription for the current user.

#parameters

idstringID of the subscription to cancel.
example: `sub_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const subscription = await client.subscription.delete('sub_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(subscription.data);
}

main();

#Token

GET

/token

list tokens

GET

/token/{id}

get token

POST

/token

create token

DELETE

/token/{id}

delete token

get

/token

List the current user's personal access tokens.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const tokens = await client.token.list();

  console.log(tokens.data);
}

main();
get

/token/{id}

Get the personal access token with the given ID.

#parameters

idstringID of the personal token to get.
example: `pat_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const token = await client.token.get('pat_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(token.data);
}

main();
post

/token

Create a personal access token.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const token = await client.token.create();

  console.log(token.data);
}

main();
delete

/token/{id}

Delete the personal access token with the given ID.

#parameters

idstringID of the personal token to delete.
example: `pat_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const token = await client.token.delete('pat_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(token.data);
}

main();

#App (OAuth)

GET

/app

list apps

GET

/app/{id}

get app

POST

/app

create app

DELETE

/app/{id}

delete app

get

/app

List the current user's registered apps.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const apps = await client.app.list();

  console.log(apps.data);
}

main();
get

/app/{id}

Get the app with the given ID.

#parameters

idstringID of the app to get.
example: `cli_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const app = await client.app.get('cli_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(app.data);
}

main();
post

/app

Create an app.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const app = await client.app.create({ name: 'Example App', redirectURI: 'https://example.com/callback' });

  console.log(app.data);
}

main();
delete

/app/{id}

Delete the app with the given ID.

#parameters

idstringID of the app to delete.
example: `cli_XXXXXXXXXXXXXXXXXXXXXXXXX`

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const app = await client.app.delete('cli_XXXXXXXXXXXXXXXXXXXXXXXXX');

  console.log(app.data);
}

main();

#Miscellaneous

GET

/view/init

get app data

POST

/email

subscribe email

public

get

/view/init

Get initial app data, including user, products, cart, addresses, cards, subscriptions, and orders.

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const response = await client.view.init();

  console.log(response.data);
}

main();
post

/email

public

Subscribe to email updates from Terminal.

#request

#responses

#examples

import Terminal from '@terminaldotshop/sdk';

const client = new Terminal({
  bearerToken: process.env['TERMINAL_BEARER_TOKEN'], // This is the default and can be omitted
});

async function main() {
  const email = await client.email.create({ email: 'john@example.com' });

  console.log(email.data);
}

main();