# Run an integration action

```http
PUT https://secure.yoprint.com/v1/api/store/{team_slug}/setting/external_integration/{id}/action
```

- API version: v1
- Operation ID: `v1_public_external_integration_action`
- Section: Team settings › [Integrations](https://developer.yoprint.com/reference/integrations.md)
- Web page: https://developer.yoprint.com/reference/integrations/v1-external-integration-action/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Runs a one-off action on an integration. Send its `type`; the allowed values depend on the integration:

- **QuickBooks Online**: `account` and `tax` (read them), `refresh_account`, `refresh_qbo_accounts`, `refresh_qbo_tax` (reload data from QuickBooks), `check`, `upsert_yoprint_item` (set up YoPrint's item in QuickBooks), `reauth` (a new connect link, usable only in YoPrint's web app), and `customer_payment_sync`: a page of the payments customers made in the customer portal and where each stands in QuickBooks (optionally only one order's, with `order_id`; `page` and `per_page` up to 100). It reads YoPrint only, so it works even while QuickBooks needs signing in again.
- **GoShippo**: `reauth`, which returns `{"type": "oauth", "url": "..."}`.
- **Square**: `reauth`, or `transfer_confirm` / `transfer_cancel` for a Square account another YoPrint team holds (confirm returns the integration; cancel removes this team's waiting connection and answers `data: null`).
- **Shopify**: `toggle`, `self_heal_setup`, `manually_sync` (with `shopify_order_id`), `bulk_manually_sync` (with `shopify_order_ids`), and fulfillment actions with `shipment_id` or `shipment_ids`.

A `reauth` link is a YoPrint connect link that only the web app can use: opened in a browser tab or from a script it shows a refusal page. To sign in to the provider again, use Reconnect in Settings > Apps.

Suppliers and Twilio have no actions. The `{id}` is the integration's id from the list.

## Permission

Needs the Manage Settings permission. The team owner always has it.

## Side effects

- Calls the provider. Shopify fulfillment actions change orders in your Shopify store (and may email the customer); QuickBooks `upsert_yoprint_item` writes to QuickBooks; Square `transfer_confirm` disconnects the Square account from the other YoPrint team and emails that team's owner (this integration then reads `ACTION_REQUIRED` until its locations are set); `transfer_cancel` removes this team's waiting connection.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `id` (string, required): The integration, from the integration list. Its hash id from an earlier answer; there is no unique key for it. Example `d9ZxWgBz09mDFq`.

## Request body

Content type `application/json`, required.

Which integration? Send any of these 4 bodies: **QuickBooks Online**, **GoShippo**, **Square**, **Shopify**.

### QuickBooks Online

Variant 1 of 4. On the web page: https://developer.yoprint.com/reference/integrations/v1-external-integration-action/#variant-quickbooks-online

Read or refresh the accounts and tax data YoPrint keeps from QuickBooks, check the setup, set up the YoPrint item, get a new connect link (usable only in YoPrint's web app), or list how customer portal payments stand in QuickBooks (`customer_payment_sync`).

Fields:

- `type` (string, required): One of: `"account"`, `"tax"`, `"check"`, `"refresh_account"`, `"refresh_qbo_accounts"`, `"refresh_qbo_tax"`, `"upsert_yoprint_item"`, `"reauth"`, `"customer_payment_sync"`.
- `order_id` (string, optional): For `customer_payment_sync`: only the payments on this sales order or quote (its id).
- `page` (integer, optional): For `customer_payment_sync`: the page, from 1. Minimum 1.
- `per_page` (integer, optional): For `customer_payment_sync`: rows per page, 20 when left out. Minimum 1. Maximum 100.

Example request (QuickBooks Online):

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/setting/external_integration/d9ZxWgBz09mDFq/action' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "refresh_qbo_accounts"
  }'
```

### GoShippo

Variant 2 of 4. On the web page: https://developer.yoprint.com/reference/integrations/v1-external-integration-action/#variant-goshippo

Get a new GoShippo connect link (usable only in YoPrint's web app).

Fields:

- `type` (string, required): Always `"reauth"`.

Example request (GoShippo):

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/setting/external_integration/d9ZxWgBz09mDFq/action' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "reauth"
  }'
```

### Square

Variant 3 of 4. On the web page: https://developer.yoprint.com/reference/integrations/v1-external-integration-action/#variant-square

Get a new Square connect link (usable only in YoPrint's web app), or confirm or cancel moving a Square account that another team holds.

Fields:

- `type` (string, required): One of: `"reauth"`, `"transfer_confirm"`, `"transfer_cancel"`.

Example request (Square):

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/setting/external_integration/d9ZxWgBz09mDFq/action' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "reauth"
  }'
```

### Shopify

Variant 4 of 4. On the web page: https://developer.yoprint.com/reference/integrations/v1-external-integration-action/#variant-shopify

Turn sync on or off, repair the setup, sync orders by hand, or create, update or cancel fulfillments in Shopify.

Fields:

- `type` (string, required): One of: `"self_heal_setup"`, `"toggle"`, `"manually_sync"`, `"bulk_manually_sync"`, `"create_fulfillment"`, `"update_fulfillment"`, `"cancel_fulfillment"`, `"bulk_create_fulfillment"`, `"bulk_update_fulfillment"`, `"bulk_cancel_fulfillment"`.
- `notify_customer` (boolean | null, optional): For the fulfillment actions: whether Shopify emails the customer.
- `shipment_id` (string, optional): Required for the single fulfillment actions.
- `shipment_ids` (array of strings, optional): Required for the bulk fulfillment actions.
- `shopify_order_id` (string, optional): Required for `manually_sync`.
- `shopify_order_ids` (array of strings, optional): Required for `bulk_manually_sync`.

Example request (Shopify):

```bash
curl -X PUT 'https://secure.yoprint.com/v1/api/store/your-team/setting/external_integration/d9ZxWgBz09mDFq/action' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "shopify_order_id": "1001",
    "type": "manually_sync"
  }'
```

## Response

`200` Successful response.

> **Warning: a 200 answer can still be a refusal.** Check `success` (and the fields named below) as well as the HTTP status.
> - QuickBooks Online with a `type` it doesn't know: the answer is HTTP 200 with an empty body (not JSON), and nothing happens. Fix: Use a `type` from the list.

Fields:

- `data` (object | object | array, required)
  - Any of:
    - **Connect link**: A YoPrint connect link that only YoPrint's web app can use. Settings > Apps posts it with the signed-in person's session; YoPrint then ties the connection to that person and browser and sends them on to the provider's sign-in, and the provider sends them back to YoPrint, which saves the connection. Opened any other way (in a browser tab, from a script, or by someone else) it shows a refusal page and connects nothing.
      - `type` (string, required): Always `"oauth"`.
      - `url` (string (uri), required): The connect link, on YoPrint's own address (`/callback/integration_connect/...`). It works once, within 2 minutes, and only from YoPrint's web app for the person whose API key asked for it.
    - **QuickBooks Online `customer_payment_sync`: customer portal payments and their QuickBooks state**
      - `aggregate` (object, required): A summary: of this page, or with `order_id` of every payment on that order.
        - `component` (string, required): Always `"bulk_payment_sources"`.
        - `needs_attention` (integer, required): Payments that are `held` or `failed`.
        - `pending` (integer, required)
        - `scope` (string, required): One of: `"page"`, `"order"`.
        - `status` (string, required): One of: `"not_applicable"`, `"up_to_date"`, `"pending"`, `"needs_attention"`.
        - `total` (integer, required)
      - `items` (array of objects, required): Newest first.
        - Each item:
          - `amount` (string, required): The amount paid. A decimal string, such as `"125.0000"`; parse it as a decimal.
          - `confirmed_at` (string (date-time) | null, required): When YoPrint last read the Payment back from QuickBooks and found it right, or null.
          - `currency` (string, required): Its currency code, such as `USD`.
          - `customer` (object, required)
            - `id` (string, required)
            - `name` (string, required)
          - `funding_id` (string, required): The payment the customer made in the customer portal.
          - `payment_status` (string, required): One of: `"received"`, `"partially_refunded"`, `"refunded"`.
          - `projection_id` (string | null, required): YoPrint's record of the matching QuickBooks Payment, or null before one is prepared.
          - `reason` (object | null, required): Why it isn't simply up to date: `code`, a `message` for people, `detail` (or null), and `quickbooks_message`, QuickBooks' own words when it refused (or null). Null when there is nothing to say.
            - `code` (string, optional)
            - `detail` (string | null, optional)
            - `message` (string, optional)
            - `quickbooks_message` (string | null, optional)
          - `state` (string, required): `synced`: in QuickBooks and up to date. `pending`: waiting, running, or payment sync is off. `failed`: needs someone to look. `held`: held back, see `reason`. `switched_off`: every order it pays is kept out of QuickBooks. `deleted`: refunded to zero and deleted in QuickBooks. One of: `"synced"`, `"pending"`, `"failed"`, `"held"`, `"switched_off"`, `"deleted"`.
      - `pagination` (object, required)
        - `last_page` (integer, required)
        - `page` (integer, required)
        - `per_page` (integer, required)
        - `total` (integer, required)
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "type": "oauth",
    "url": "https://secure.yoprint.com/callback/integration_connect/EXAMPLE_CONNECT_LINK"
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: QuickBooks `customer_payment_sync`: the person behind the key holds no permission group with Manage Settings (`error.code` `customer_payment_sync_not_authorized`). Being the team owner is not enough here. Fix: Use the key of a member whose permission group has Manage Settings.
  - When: Your role lacks Manage Settings. The body is `{"message": "Insufficient Permission"}`, without the error envelope. Fix: Use the key of a member whose role has Manage Settings, or the owner's.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: No integration of your team has this id. `error.code` is null; `error.message` names the record type. Fix: Use an id from the list.
  - When: QuickBooks `customer_payment_sync`: `order_id` is not the id of one of your team's orders. Fix: Use a sales order or quote id from your team.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `type` is missing or not allowed for this integration (`validation_failed`). Shopify's list has no `oauth`. Fix: Use a `type` listed for it.
  - When: Square `transfer_confirm` or `transfer_cancel` when no transfer is waiting: `error.code` `integration_transfer_not_pending`. Fix: Read the integration first.
  - When: QuickBooks `customer_payment_sync`: `page` or `per_page` is not a whole number in range, or `order_id` is not a string (`validation_failed`). Fix: Send `page` from 1 and `per_page` from 1 to 100.
  - When: The integration is not in your plan (`plan_limitation`). Fix: Upgrade the plan, or use another integration.
  - When: The integration is retired (`integration_deprecated`). Fix: Delete it and connect an alternative.
- `500` A business rule refused the request (see the operation's errors), or something failed inside YoPrint. Refusals use the error envelope with a code such as `action_not_allowed`; an unexpected failure answers `{"message": "Server Error"}`. Repeating a refusal gets the same answer; after an unexpected failure, read the record back before you retry a change.
  - When: A supplier or Twilio integration: `error.code` `no_action`, "No action found!". Fix: They have no actions.

## Related

- [Read data from an integration's provider](https://developer.yoprint.com/reference/integrations/v1-external-integration-data.md): `PUT /v1/api/store/{team_slug}/setting/external_integration/{id}/data`
- [Get an integration](https://developer.yoprint.com/reference/integrations/v1-external-integration-show.md): `GET /v1/api/store/{team_slug}/setting/external_integration/{external_integration_reference}`
