# Quickstart

> Get an API key, make your first call and create a customer, in under five minutes with curl.

Web page: https://developer.yoprint.com/start/quickstart/

In this quickstart you check your key, read your team's customers, create a customer and read it back. You need a terminal with `curl`.

> **Caution:** There's no sandbox: everything here runs on your real team's data. Step 3 creates a real customer, "TEST Northwind Apparel", which you delete at the end. See [Test your integration](https://developer.yoprint.com/start/testing.md) for safer ways to try writes.

## 1. Get your key and Team ID

API access comes with these plans:

| Includes API access                       | Doesn't                    |
| ----------------------------------------- | -------------------------- |
| Pro, monthly or annual, and the Pro trial | Basic, and the Basic trial |
| The Special plan                          | Free                       |
| The older Essential and Enterprise plans  | The older Starter plan     |

Creating a key in **Profile** also needs an active, paid subscription.

1. Sign in to YoPrint and open **Profile**.
2. Find the **API Access** card. If it says "You don't have an API key yet.", select **Create API Key**. Opening the page never creates a key.
3. Copy the key with the copy button next to it, which always copies the whole key. YoPrint shows a new key in full. After that the card shows it masked, and **Reveal** shows it again.
4. On the same card, copy the **Team ID**. That's your team slug, the value that goes in every request path.

- **No API Access card in Profile?** Your team's plan doesn't include API access. A team owner can move the team to Pro or higher.
- **The card says "API keys need an active subscription. If you're on a trial and want to try the API, email support\@yoprint.com."?** Your team is on a trial, and Profile creates keys only on a paid subscription. Email support to try the API during the trial. If you already have a key, it works on a Pro trial team too. See [Test your integration](https://developer.yoprint.com/start/testing.md).

Your key acts as you, with your role, on every team you belong to whose plan includes API access. Keep it secret. See [Authentication](https://developer.yoprint.com/concepts/authentication.md).

## 2. Make your first request

The **API Access** card has a **Make your first request** section with this request, with your Team ID already in place of `your-team`. Copy it, replace `YOUR_API_KEY` with your key, and run it:

`GET /v1/api/store/{team_slug}/is_authenticated` [Check that your API key works for a team](https://developer.yoprint.com/reference/api-key/v1-misc-is-authenticated.md)

```bash
curl https://secure.yoprint.com/v1/api/store/your-team/is_authenticated \
  -H "Authorization: Bearer YOUR_API_KEY"
```

A working key and Team ID get back:

```json
{
  "status": 200,
  "success": true,
  "data": { "is_authenticated": true }
}
```

That's your first successful call. If you got something else:

| You got                                       | What it means                                                                 | Fix                                                                 |
| --------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `401` with `"code": "unauthenticated"`        | The key is wrong, or it was regenerated.                                      | Copy it again from Profile. Check that you replaced `YOUR_API_KEY`. |
| `403` with `"code": "api_access_not_in_plan"` | The key works, but this team's plan doesn't include API access.               | Use a team on Pro or higher, or upgrade this one.                   |
| `404` with `"code": "page_not_found"`         | The key works, but the Team ID is wrong, or you're not a member of that team. | Copy the **Team ID** again.                                         |

The `403` looks like this:

```json
{
  "status": 403,
  "success": false,
  "error": {
    "code": "api_access_not_in_plan",
    "message": "Your team's plan doesn't include API access. Upgrade to the Pro plan or higher in YoPrint, under Billing, to use the API, webhooks and Zapier."
  }
}
```

Put your key and Team ID in your shell so the commands below can use them:

```bash
export YOPRINT_API_KEY="YOUR_API_KEY"
export YOPRINT_TEAM="your-team"
```

From here on, each request also sends two headers:

- `Accept: application/json`, so that even a mistyped path answers JSON instead of an HTML page.
- `X-Yoprint-Decimal-Format: exact-v1`, so amounts come back exact. See [Money and quantities](https://developer.yoprint.com/concepts/money-and-quantities.md#ask-for-exact-responses).

Now read the first page of your team's customers:

`GET /v1/api/store/{team_slug}/customer` [List customers](https://developer.yoprint.com/reference/customers/v1-customer-index.md)

```bash
curl "https://secure.yoprint.com/v1/api/store/$YOPRINT_TEAM/customer" \
  -H "Authorization: Bearer $YOPRINT_API_KEY" \
  -H "Accept: application/json" \
  -H "X-Yoprint-Decimal-Format: exact-v1"
```

The answer has the customers in `data`, and a `pagination` block that says how many there are and how many pages. Shortened:

```json
{
  "status": 200,
  "success": true,
  "data": [
    { "id": "63KcENAAsKuipY", "name": "Alex Rivera", "tax_exempt": false }
  ],
  "pagination": { "count": 1, "total": 1, "perPage": 50, "currentPage": 1, "totalPages": 1, "links": [] }
}
```

Each customer's `id`, such as `63KcENAAsKuipY`, is how you name it in later requests. It isn't the number people see in the web app. See [IDs](https://developer.yoprint.com/concepts/ids.md).

## 3. Make your first write

Create a customer with one contact:

`POST /v1/api/store/{team_slug}/customer` [Create a customer](https://developer.yoprint.com/reference/customers/v1-customer-store.md)

```bash
curl "https://secure.yoprint.com/v1/api/store/$YOPRINT_TEAM/customer" \
  -H "Authorization: Bearer $YOPRINT_API_KEY" \
  -H "Accept: application/json" \
  -H "X-Yoprint-Decimal-Format: exact-v1" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "name": "TEST Northwind Apparel",
      "tax_exempt": false
    },
    "contact": [
      {
        "first_name": "Alex",
        "last_name": "Rivera",
        "email": "alex@example.com",
        "send_invoice": true,
        "is_primary": true
      }
    ]
  }'
```

- `customer.name` and `customer.tax_exempt` are required.
- `contact` is a list. Each contact needs `first_name`, `send_invoice` and `is_primary`. A phone number also needs its country, in `phone_country`.
- Use your own email address for the contact. Later guides can email this customer.

The answer is the new customer, with its contacts. Note its `data.id`:

```json
{
  "status": 200,
  "success": true,
  "data": {
    "id": "VwYKuTP9vd8Dfo",
    "name": "TEST Northwind Apparel",
    "tax_exempt": false,
    "contacts": [
      { "id": "ZXhN3KtjHgQZFz", "first_name": "Alex", "last_name": "Rivera", "email": "alex@example.com" }
    ]
  }
}
```

Keep it in your shell for the next steps:

```bash
export CUSTOMER_ID="VwYKuTP9vd8Dfo"
```

If you get `422`, the body's `error.fields` names each field to fix. Nothing was created. Fix the request and send it again.

> **Caution:** Don't send a create twice. If the request times out, list or search your customers before you try again, or you may end up with two "TEST Northwind Apparel" customers. See [Retries and duplicates](https://developer.yoprint.com/concepts/retries-and-duplicates.md).

The new customer is assigned to you, and YoPrint fires the `customer.created` webhook for any subscription that listens to it.

## 4. Read it back

`GET /v1/api/store/{team_slug}/customer/{hash_id}` [Get a customer](https://developer.yoprint.com/reference/customers/v1-customer-show.md)

```bash
curl "https://secure.yoprint.com/v1/api/store/$YOPRINT_TEAM/customer/$CUSTOMER_ID" \
  -H "Authorization: Bearer $YOPRINT_API_KEY" \
  -H "Accept: application/json" \
  -H "X-Yoprint-Decimal-Format: exact-v1"
```

You get the same customer, with its contacts and addresses. Open **Customers** in the web app and you'll see it there too.

To try an order next, keep this customer and go to [Quote to payment](https://developer.yoprint.com/guides/quote-to-payment.md). It uses `$CUSTOMER_ID`.

## 5. Clean up

Delete the test customer:

`DELETE /v1/api/store/{team_slug}/customer/{hash_id}` [Delete a customer](https://developer.yoprint.com/reference/customers/v1-customer-destroy.md)

```bash
curl -X DELETE "https://secure.yoprint.com/v1/api/store/$YOPRINT_TEAM/customer/$CUSTOMER_ID" \
  -H "Authorization: Bearer $YOPRINT_API_KEY" \
  -H "Accept: application/json" \
  -H "X-Yoprint-Decimal-Format: exact-v1"
```

Deleting moves the customer to the trash, where it can be restored. A customer with an open quote or sales order can't be deleted: YoPrint answers `422`. Delete the order first.

## What you learned

- Every request goes to `https://secure.yoprint.com`, with the version and your team slug at the start of the path.
- Every request carries `Authorization: Bearer YOUR_API_KEY`, and should carry `Accept: application/json` and `X-Yoprint-Decimal-Format: exact-v1`.
- Records are named by their `id`, from a previous answer.
- Answers have `status`, `success` and `data`. Lists add `pagination`.
- A create isn't safe to repeat.

## Next

- [Quote to payment](https://developer.yoprint.com/guides/quote-to-payment.md): create a sales order, add lines, invoice it and record a payment.
- [Calling the API](https://developer.yoprint.com/concepts/calling-the-api.md): the same calls in JavaScript, Python and PHP.
- [Errors](https://developer.yoprint.com/concepts/errors.md) and [Money and quantities](https://developer.yoprint.com/concepts/money-and-quantities.md): the two pages that prevent most bugs.
