{"id":27288552,"url":"https://github.com/channelape/channelape-typescript-sdk","last_synced_at":"2025-04-11T20:58:02.184Z","repository":{"id":30267673,"uuid":"124440932","full_name":"ChannelApe/channelape-typescript-sdk","owner":"ChannelApe","description":"TypeScript and JavaScript SDK for the ChannelApe REST API","archived":false,"fork":false,"pushed_at":"2024-05-17T13:57:18.000Z","size":1828,"stargazers_count":13,"open_issues_count":1,"forks_count":5,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-11T20:57:52.627Z","etag":null,"topics":["channelape","ecommerce","rest","rest-client","sdk","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChannelApe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-08T19:55:12.000Z","updated_at":"2024-05-17T13:57:18.000Z","dependencies_parsed_at":"2024-05-13T18:40:52.530Z","dependency_job_id":"56836002-f3a7-4a29-9091-40cf97bb9139","html_url":"https://github.com/ChannelApe/channelape-typescript-sdk","commit_stats":null,"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChannelApe%2Fchannelape-typescript-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChannelApe%2Fchannelape-typescript-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChannelApe%2Fchannelape-typescript-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChannelApe%2Fchannelape-typescript-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChannelApe","download_url":"https://codeload.github.com/ChannelApe/channelape-typescript-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480466,"owners_count":21110936,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["channelape","ecommerce","rest","rest-client","sdk","typescript"],"created_at":"2025-04-11T20:58:01.009Z","updated_at":"2025-04-11T20:58:02.165Z","avatar_url":"https://github.com/ChannelApe.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ChannelApe SDK\n\nTypeScript and JavaScript SDK for the [ChannelApe REST API](https://docs.channelape.io/)\n\n[![Build Status](https://github.com/ChannelApe/channelape-typescript-sdk/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/ChannelApe/channelape-typescript-sdk/actions)  [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=channelape-typescript-sdk\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=channelape-typescript-sdk) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=channelape-typescript-sdk\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=channelape-typescript-sdk)\n\n## Features\n- [Getting Started](#getting-started)\n- [Errors](#errors)\n- [Sessions](#sessions)\n- [Actions](#actions)\n- [Channels](#channels)\n- [Suppliers](#suppliers)\n- [Orders](#orders)\n- [Variants](#variants)\n- [Businesses](#businesses)\n  - [API Accounts](#apiAccounts)\n- [Subscriptions](#subscriptions)\n- [Order Activities](#order-activities)\n- [Analytics](#analytics)\n- [Product Filters](#product-filters)\n- [Users](#users)\n- [Inventories](#inventories)\n  - [Inventory Quantities](#inventory-quantities)\n- [Locations](#locations)\n- [Steps](#steps)\n- [Plays](#plays)\n- [Batches](#batches)\n  - [Batch Inventory Adjustments](#batchInventoryAdjustments)\n\n### Getting Started\n\nThe ChannelApe SDK is asynchronous and all functions return promises.\n\n#### Creating a client\n\nCreate a new instance of the ChannelApeClient with your sessionId.\n\n```typescript\nconst channelApeClient = new ChannelApeClient({\n  sessionId: '4674b668-c4d2-4270-bf9b-ebaab78c378d'\n});\n```\n\n#### Optional client configurations\n\n* timeout - Number of milliseconds to wait for the API to send response headers. Defaults to 180000 (3 minutes). Cannot be set lower than 2000 (2 seconds).\n* endpoint - Environment endpoint you would like to hit. Defaults to https://api.channelape.com\n* logLevel - Level of logs you wish to see from the SDK. Defaults to OFF.\n* maximumRequestRetryTimeout - Number of milliseconds to keep retrying a request for when an undesired response status code is received. Defaults to 180000 (3 minutes). Cannot be set lower than 2000 (2 seconds).\n* minimumRequestRetryRandomDelay - Minimum number of milliseconds to randomly delay by when an undesired response status code is received. Defaults to 1000 (1 second). Cannot be set lower than 1000 (1 second).\n* maximumRequestRetryRandomDelay - Maximum number of milliseconds to randomly delay by when an undesired response status code is received. Defaults to 5000 (5 seconds). Cannot be set lower than 2000 (2 seconds).\n* maximumConcurrentConnections - Maximum number of connections or requests that can be made to the API at a single time.  Defaults to 5.\n\n\n### Error Handling\n\nWhen a call to the ChannelApe API returns an error, it can be accessed through the `ApiErrors` array on the error object.  The following is an example:\n```typescript\ntry {\n  newOrder = await client.orders().create(orderWithChannelOrderIdThatAlreadyExists);\n} catch (error) {\n  if (error?.ApiErrors?.code === 168) {\n    ... Handle duplicate channel order ID error\n  }\n}\n```\n\nError codes and descriptions can be found here: [Postman API Error Handling](https://docs.channelape.io/?version=latest#error-handling)\n\n\n### Sessions\n\n#### Get Session\nA User Account session will include your `userId` which is useful when retrieving [Businesses](#Businesses). API Account sessions will return an `apiAccountId` instead.\n```typescript\nchannelApeClient.sessions().get(sessionId)\n  .then((session: Session) =\u003e {\n    // do what you need to do with session data here\n    // session will also include your userId or apiAccountId\n  });\n```\n\n### Actions\n\n#### Get action\n```typescript\nchannelapeClient.actions().get(actionId)\n  .then((action: Action) =\u003e {\n    // do what you need to do with action data here\n  });\n```\n\n#### Complete action\n```typescript\nchannelapeClient.actions().complete(actionId)\n  .then((action: Action) =\u003e {\n    // do what you need to do with action data here\n  });\n```\n\n#### Update action with error\n```typescript\nchannelapeClient.actions().error(actionId)\n  .then((action: Action) =\u003e {\n    // do what you need to do with action data here\n  });\n```\n\n#### Update action health check\n```typescript\nchannelapeClient.actions().updateHealthCheck(actionId)\n  .then((action: Action) =\u003e {\n    // do what you need to do with action data here\n  });\n```\n\n### Channels\n\n#### Get channel\n```typescript\nchannelapeClient.channels().get(channelId)\n  .then((channel: Channel) =\u003e {\n    // do what you need to do with channel data here\n  });\n```\n\n#### Get all channels for a business\n```typescript\nchannelapeClient.channels().get({ businessId: 'some-valid-business-id' })\n  .then((channels: Channel[]) =\u003e {\n    // do what you need to do with channel data here\n  });\n```\n\n#### Create a channels for a business\n```typescript\nchannelapeClient.channels().create({\n      additionalFields: [],\n      integrationId: 'some-valid-integration-id',\n      name: 'channel-name',\n      credentials: {\n        healthCheckInterval: 300,\n        payloadUrl: 'channelape.com'\n      },\n      businessId: 'some-valid-business-id',\n      enabled: true\n    })\n  .then((channels: Channel) =\u003e {\n    // do what you need to do with channel data here\n  });\n```\n\n#### Update a channels for a business\n```typescript\nchannelapeClient.channels().update({\n      additionalFields: [],\n      id: 'valid-channel-id'\n      integrationId: 'some-valid-integration-id',\n      name: 'channel-name',\n      credentials: {\n        healthCheckInterval: 300,\n        payloadUrl: 'channelape.com'\n      },\n      businessId: 'some-valid-business-id',\n      enabled: true\n    })\n  .then((channels: Channel) =\u003e {\n    // do what you need to do with channel data here\n  });\n```\n\n### Suppliers\n\n#### Get supplier\n```typescript\nchannelapeClient.suppliers().get(supplierId)\n  .then((supplier: Supplier) =\u003e {\n    // do what you need to do with supplier data here\n  });\n```\n\n#### Get all suppliers for a business\n```typescript\nchannelapeClient.suppliers().get({ businessId: 'some-valid-business-id' })\n  .then((suppliers: Supplier[]) =\u003e {\n    // do what you need to do with supplier data here\n  });\n```\n\n#### Update a supplier\n```typescript\nchannelapeClient.suppliers().update(supplierUpdateRequest)\n  .then((supplier: Supplier) =\u003e {\n    // do what you need to do with supplier data here\n  });\n```\n#### Create a supplier\n```typescript\nchannelapeClient.suppliers().create(SupplierCreateRequest)\n  .then((supplier: Supplier) =\u003e {\n    // do what you need to do with supplier data here\n  });\n```\n\n### Orders\n\n#### Get order\n```typescript\nchannelapeClient.orders().get(orderId)\n  .then((order: Order) =\u003e {\n    // do what you need to do with order data here\n  });\n```\n\n#### Update order\n```typescript\nchannelapeClient.orders().update(order)\n  .then((updatedOrder: Order) =\u003e {\n    // do what you need to do with updatedOrder data here\n  });\n```\n\n#### Patch order\n```typescript\nchannelapeClient.orders().patch(order)\n  .then((patchedOrder: Order) =\u003e {\n    // do what you need to do with patchedOrder data here\n  });\n```\n\n#### Create order\n````typescript\nconst orderToCreate: OrderCreateRequest = {\n  additionalFields: [\n    { name: 'name', value: 'CA1001' },\n    { name: 'order_number', value: '1001' }\n  ],\n  totalPrice: 295.99,\n  alphabeticCurrencyCode: 'USD',\n  channelId: 'your-channel-id',\n  channelOrderId: 'specify-your-channel-order-id',\n  customer: {\n    firstName: 'John',\n    lastName: 'Smith',\n    name: 'John Smith',\n    additionalFields: [\n      { name: 'extraCustomerData', value: 'Put whatever you would like here' }\n    ]\n  },\n  status: OrderStatus.OPEN,\n  purchasedAt: new Date(),\n  lineItems: [{\n    id: 'some-line-item-id',\n    quantity: 1,\n    sku: 'NCC1701D',\n    title: 'A model space ship',\n    additionalFields: [\n      { name: 'extraLineItemData', value: 'Put whatever you would like here' }\n    ]\n  }]\n};\nchannelapeClient.orders().create(orderCreateRequest)\n  .then((createdOrder: Order) =\u003e {\n    // do what you need to do with the createdOrder data here\n  });\n````\n\n### Variants\n\n#### Get Variant\n```typescript\nconst variantsRequest: VariantsRequest = {\n  productId,\n  inventoryItemValue\n};\nchannelApeClient.variants().get(variantsRequest)\n  .then((variant: Variant) =\u003e {\n    // do what you need to do with variant data here\n  });\n```\n\n#### Get Variants for a Product\n```typescript\nconst variantsRequestByProductId: VariantsRequestByProductId = {\n  productId\n};\nchannelApeClient.variants().get(variantsRequestByProductId)\n  .then((variants: Variant[]) =\u003e {\n    // do what you need to do with variant array\n  })\n```\n\n#### Get Variant Search Results for a Vendor\n````typescript\nconst variantsRequest: VariantsSearchRequestByVendor = {\n  vendor,\n  businessId\n};\nchannelApeClient.variants().search(variantsRequest)\n  .then((variantSearchResults: VariantSearchResults[]) =\u003e {\n    // do what you need to do with Variant Search Results array\n  });\n````\n\n#### Get Variant Search Results using a Product Filter\n````typescript\nconst variantsRequest: VariantsSearchRequestByProductFilterId = {\n  productFilterId\n};\nchannelApeClient.variants().search(variantsRequest)\n  .then((variantSearchResults: VariantSearchResults[]) =\u003e {\n    // do what you need to do with Variant Search Results array\n  });\n````\n\n#### Get Variant Search Results for a SKU\n\n* *exactMatch* parameter if set to true will only match the exact sku set on the request instead of all sku's that start with that given character sequence.\n\n````typescript\nconst variantsRequest: VariantsSearchRequestBySku = {\n  sku,\n  businessId,\n  exactMatch: true\n};\nchannelApeClient.variants().search(variantsRequest)\n  .then((variantSearchResults: VariantSearchResults[]) =\u003e {\n    // do what you need to do with Variant Search Results array\n  });\n````\n\n#### Get Variant Search Results for a UPC\n\n* *exactMatch* parameter if set to true will only match the exact upc set on the request instead of all upc's that start with that given character sequence.\n\n````typescript\nconst variantsRequest: VariantsSearchRequestByUpc = {\n  upc,\n  businessId,\n  exactMatch: true\n};\nchannelApeClient.variants().search(variantsRequest)\n  .then((variantSearchResults: VariantSearchResults[]) =\u003e {\n    // do what you need to do with Variant Search Results array\n  });\n````\n\n#### Get Variant Search Results for a Tag\n````typescript\nconst variantsRequest: VariantsSearchRequestByTag = {\n  tag,\n  businessId\n};\nchannelApeClient.variants().search(variantsRequest)\n  .then((variantSearchResults: VariantSearchResults[]) =\u003e {\n    // do what you need to do with Variant Search Results array\n  });\n````\n\n\n### Businesses\n\n#### Get Business\n```typescript\nconst businessesQueryRequestByBusinessId: BusinessesQueryRequestByBusinessId = {\n  businessId\n}\nchannelApeClient.businesses().get(businessesQueryRequestByBusinessId)\n  .then((business: Business) =\u003e {\n    // do what you need to do with business data here\n  });\n```\n\n#### Get Businesses\n```typescript\nconst businessesQueryRequestByUserId: BusinessesQueryRequestByUserId = {\n  userId\n}\nchannelApeClient.businesses().get(businessesQueryRequestByUserId)\n  .then((businesses: Business[]) =\u003e {\n    // do what you need to do with businesses array data here\n  });\n```\nSee [Sessions](#sessions) for how to retrieve your `userId`\n\n#### Get Business Member\n```typescript\nconst businessMemberRequest: BusinessMemberRequest = {\n  userId,\n  businessId\n}\nchannelApeClient.businesses().getBusinessMember(businessMemberQueryRequest)\n  .then((businessMember: BusinessMember) =\u003e {\n    // do what you need to do with the business member here\n  });\n```\n\n#### Get Business Members\n```typescript\nconst businessMemberRequest: BusinessMemberRequest = {\n  userId,\n  businessId\n}\nchannelApeClient.businesses().getBusinessUsers(businessId)\n  .then((users: User[]) =\u003e {\n    // do what you need to do with the business members here\n  });\n```\n\n#### Invite a Member to a business\n```typescript\nconst businessId = 'valid-business-id';\nconst email = 'valid-email-id';\nchannelApeClient.businesses().inviteMember(email, businessId)\nthen((invitationMember: InvitationResponse) =\u003e {\n    // send invitationMember to a user\n  });\n```\n\n#### Remove a Member from a business\n```typescript\nconst businessId = 'valid-business-id';\nconst userId = 'valid-id';\nchannelApeClient.businesses().removeMember(businessId, userId)\nthen((removedMember: BusinessMember) =\u003e {\n    // remove a member from business\n  });\n```\n#### Update a Business's Settings\n```typescript\nconst businessToUpdate: Business = {\n  name: 'name',\n  inventoryItemKey: InventoryItemKey.SKU,\n  timeZone: TimeZoneId.US_ALASKA,\n  alphabeticCurrencyCode: AlphabeticCurrencyCode.USD,\n  id: 'valid-id',\n  embeds: [],\n  errors: []\n}\nchannelApeClient.businesses().update(businessToUpdate)\n  .then((updatedBusiness: Business) =\u003e {\n    // do what you need to do with the updated business here \n  });\n```\n#### Verify Business Member\n```typescript\nconst verificationCode = '1234567';\nchannelApeClient.businesses().verifyBusinessMember(verificationCode)\n  .then((business: Business) =\u003e {\n    // do what you need to do with the business here\n  });\n```\n\n#### Create Business\n```typescript\nconst businessToCreate: BusinessCreateRequest = {\n  name: 'Valid Business Name',\n  timeZone: TimeZoneId.AMERICA_NEW_YORK,\n  inventoryItemKey: InventoryItemKey.SKU,\n  alphabeticCurrencyCode: AlphabeticCurrencyCode.USD\n}\nchannelApeClient.businesses().create(businessToCreate)\n  .then((business: Business) =\u003e {\n    // do what you need to do with the newly created business here \n  });\n```\n\n\n#### API Accounts\n\n##### Get API Account By ID\n```typescript\nconst businessId = 'valid-business-id';\nconst apiAccountId = 'valid-api-account-id';\nchannelApeClient.businesses().apiAccounts().get(businessId, apiAccountId)\n  .then((apiAccount: ApiAccount) =\u003e {\n    // do what you need to do with the API account here \n  });\n```\n\n##### Get All API Accounts for a Business\n```typescript\nconst businessId = 'valid-business-id';\nchannelApeClient.businesses().apiAccounts().get(businessId)\n  .then((apiAccount: ApiAccount[]) =\u003e {\n    // do what you need to do with the API accounts here \n  });\n```\n\n##### Create API Account\n```typescript\nconst businessId = 'valid-business-id';\nconst apiKeyName = 'some-api-key';\nchannelApeClient.businesses().apiAccounts().create(name, businessId)\n  .then((apiAccount: ApiAccount) =\u003e {\n    // do what you need to do with the API account here \n  });\n```\n\n##### Delete API Account from a business\n```typescript\nconst businessId = 'valid-business-id';\nconst apiAccountId = 'valid-api-account-id';\nchannelApeClient.businesses().apiAccounts().delete(businessId, apiAccountId)\n  .then((deleteAccount: ApiAccount) =\u003e {\n    // do what you need to do with the API account here \n  });\n```\n\n### Subscriptions\n\n#### Get Subscription\n```typescript\nconst businessId = 'valid-business-id';\nchannelApeClient.subscriptions().get(businessId)\n  .then((subscription: Subscription) =\u003e {\n    // do what you need to do with subscription data here\n  });\n```\n\n### Order Activities\nChannelApe allows you to log any arbitrary action done to or information about an order through the Order Activities endpoint.\n\n#### Create order activities\n```typescript\n// Create an order activity if you know the channelId and channelOrderId of the order in question\nconst orderActivityCreateRequest: OrderActivityCreateRequestByChannel = {\n  channelId: 'some-channel-id',\n  channelOrderId: 'some-channel-order-id-belonging-to-the-specified-channel-id',\n  operation: OrderActivityOperation.UPDATE,\n  result: OrderActivityResult.SUCCESS,\n  messages: [\n    {\n      description: 'Arbitrary text limited to 1000 characters',\n      title: 'Arbitrary text limited to 100 characters.' // Order activities are grouped by title in the ChannelApe dashboard\n    }\n  ]\n};\n\n// Create an order activity if you know the ChannelApe Order ID (i.e. order.id) of the order in question\nconst orderActivityCreateRequest: OrderActivityCreateRequestByOrderId = {\n  orderId: 'some-order-id',\n  operation: OrderActivityOperation.CREATE,\n  result: OrderActivityResult.ERROR,\n  messages: [\n    {\n      description: 'Arbitrary text limited to 1000 characters',\n      title: 'Arbitrary text limited to 100 characters.' // Order activities are grouped by title in the ChannelApe dashboard\n    }\n  ]\n};\n\n// Create an order activity if you know the channelOrderId and the businessId of the order in question\nconst orderActivityCreateRequest: OrderActivityCreateRequestByBusiness = {\n  channelOrderId: 'some-channel-order-id',\n  businessId: 'some-business-id-that-the-channel-order-id-belongs-to',\n  operation: OrderActivityOperation.CREATE,\n  result: OrderActivityResult.WARN,\n  messages: [\n    {\n      description: 'Arbitrary text limited to 1000 characters',\n      title: 'Arbitrary text limited to 100 characters.' // Order activities are grouped by title in the ChannelApe dashboard\n    }\n  ]\n};\n\nchannelApeClient.orders().activities().create(orderActivityCreateRequest).then((orderActivity) =\u003e {\n  // do what you need to do with orderActivity here\n});\n```\n\n\n### Analytics\n\n### Generate Analytics Embed\nThis can only be done with an end user account that has access to ChannelApe analytics.\n```typescript\nconst embedCode = 'valid-embed-code';\nconst timezone = 'America/New_York';\nchannelApeClient.analytics().generateEmbed(embedCode, timezone)\n  .then((embed: Embed) =\u003e {\n    // Render the embed in an iframe or in a browser.\n  });\n```\n\n### Available Analytics Embeds\n```typescript\nchannelApeClient.analytics().get()\n  .then((reports[]: Embed) =\u003e {\n    // Do what you need to with list of reports\n  });\n```\n\n### Get Analytics Token\n```typescript\nchannelApeClient.analytics().getToken()\n  .then((token: Token) =\u003e {\n    // Do what you need to with the token\n  });\n```\n\n\n### Product Filters\n\n### Create Product Filter\n```typescript\nconst productFilterRequest: ProductFilterRequest = {\n  businessId: 'valid-business-id'\n};\nchannelApeClient.productFilter().create({}, productFilterRequest)\n  .then((productFilter: ProductFilter) =\u003e {\n    // Do what you need with the filter\n  });\n```\n\n\n### Users\n\n#### Get User\n```typescript\nconst userId: string = 'some-user-id';\nchannelApeClient.users().get(userId)\n  .then((user: User) =\u003e {\n    // Do what you need with the user\n  });\n```\n\n### Inventories\n\n### Get inventory item\n```typescript\nconst inventoryItemId: string = 'some-inventory-id';\nchannelApeClient.inventories().get(inventoryItemId)\n  .then((inventoryItem: InventoryItem) =\u003e {\n    // Do what you need with the inventory item\n  });\n```\n\n### Get businesses inventory item by SKU\n```typescript\nconst inventorySku: string = 'ABC-123';\nconst businessId: string = '1';\nchannelApeClient.inventories().get(businessId, inventorySku)\n  .then((inventoryItems: InventoryItem[]) =\u003e {\n    // Do what you need with the inventory items\n  });\n```\n\n### Create new Inventory Item\n```typescript\nconst inventoryItemCreateRequest: InventoryItemCreateRequest = {\n  businessId: '1',\n  sku: 'ABC-123',\n  title: 'Cool inventory title'\n};\nchannelApeClient.inventories().create(inventoryItemCreateRequest)\n  .then((inventoryItem: InventoryItem) =\u003e {\n    // Do what you need with the created inventory item\n  });\n```\n\n### Update Inventory Item\n```typescript\nconst inventoryItemUpdateRequest: InventoryItemUpdateRequest = {\n  id: '123',\n  sku: 'ABC-123',\n  title: 'Cool inventory title'\n};\nchannelApeClient.inventories().update(inventoryItemUpdateRequest)\n  .then((inventoryItem: InventoryItem) =\u003e {\n    // Do what you need with the updated inventory item\n  });\n```\n\n### Inventory Quantities\n\n### Adjust Inventory Item Quantity\n```typescript\nconst inventoryItemId = '34';\nconst locationId = '28';\nconst quantity = 31;\nconst inventoryStatus =  InventoryStatus.AVAILABLE_TO_SELL;\nconst adjustmentRequest: AdjustmentRequest = {\n  inventoryItemId,\n  locationId,\n  quantity,\n  inventoryStatus\n};\nchannelApeClient.inventories().quantities().adjust(adjustmentRequest)\n  .then((adjustment: Adjustment) =\u003e {\n    // Do what you need with the adjustment\n  });\n```\n\n### Set Inventory Item Quantity\n- idempotentKey is optional. It will default to a UUID if nothing is provided. This key is used to \ndetermine if an adjustment should be created or if it is a duplicate.\n```typescript\nconst inventoryItemId = '34';\nconst locationId = '28';\nconst quantity = -148;\nconst inventoryStatus =  InventoryStatus.ON_ORDER;\nconst idempotentKey  = `${new Date().toISOString()}_${locationId}_${inventoryItemId}_${inventoryStatus}`;\nconst adjustmentRequest: AdjustmentRequest = {\n  inventoryItemId,\n  locationId,\n  quantity,\n  inventoryStatus,\n  idempotentKey\n};\nchannelApeClient.inventories().quantities().set(adjustmentRequest)\n  .then((adjustment: Adjustment) =\u003e {\n    // Do what you need with the adjustment\n  });\n```\n\n### Batch Update Inventory Item Quantity\n\n- If at least one adjustment fails, the call will wait for all other pending requests\nto complete and then throw an error.\n- The deduplication key specifies a string which will be used to determine if an adjustment\nshould be created.  If a key with the same string for a particular inventory item, location, \nand status was already used, it will not perform the adjustment.  For example, this can be \nused to allow only one adjustment per day so that if the batched adjustments are sent through \na second time, only the ones which failed will be recreated.\nHere is the generated key format: {deduplicationKey}\\_{locationId}\\_{inventoryItemId}\\_{status}\n\nCurrently Allowed Inventory Statuses:\n- AVAILABLE_TO_SELL\n- ON_HOLD\n- ON_HAND\n- COMMITTED\n- ON_ORDER\n\n```typescript\nconst adjustmentsBySku: AdjustmentsBySku = [{\n  sku: 'A1',\n  adjustments: [{\n    quantity: 1,\n    inventoryStatus: InventoryStatus.AVAILABLE_TO_SELL,\n    deduplicationKey: '05052020',\n    locationId: '123',\n    memo: 'Memo'\n  }, {\n    quantity: 3,\n    inventoryStatus: InventoryStatus.ON_HOLD,\n    deduplicationKey: '05052020',\n    locationId: '123',\n    memo: 'Memo'\n  }]\n}, {\n  sku: 'B1',\n  adjustments: [{\n    quantity: 2,\n    inventoryStatus: InventoryStatus.AVAILABLE_TO_SELL,\n    deduplicationKey: '05052020',\n    locationId: '123',\n    memo: 'Memo'\n  }, {\n    quantity: 0,\n    inventoryStatus: InventoryStatus.ON_HOLD,\n    deduplicationKey: '05052020',\n    locationId: '123',\n    memo: 'Memo'\n  }]\n}];\n```\n\n#### Batch Set Inventory Item Quantities\n\n```typescript\nchannelApeClient.inventories().quantities().setBatch(adjustmentsBySku)\n  .then(() =\u003e {\n    // All adjustments completed successfully\n  });\n```\n\n#### Batch Adjust Inventory Item Quantities\n\n```typescript\nchannelApeClient.inventories().quantities().adjustBatch(adjustmentsBySku)\n  .then(() =\u003e {\n    // All adjustments completed successfully\n  });\n```\n\n### Retrieve an inventory item's current quantities\n```typescript\nconst inventoryItemId = '35';\nchannelApeClient.inventories().quantities().retrieve(inventoryItemId)\n  .then((quantities: InventoryItemQuantity[]) =\u003e {\n    // Do what you need with the inventory item quantities\n  });\n```\n\n### Locations\n\n### Get location\n```typescript\nconst locationId: string = 'some-location-id';\nchannelApeClient.locations().get(locationId)\n  .then((location: Location) =\u003e {\n    // Do what you need with the location\n  });\n```\n\n### Get locations for a business\n```typescript\nconst businessId: string = '1';\nchannelApeClient.locations().getByBusinessId(businessId)\n  .then((location: Location) =\u003e {\n    // Do what you need with the locations\n  });\n```\n\n### Create new Location\n```typescript\nconst locationCreationRequest: LocationCreateRequest = {\n  businessId: '1',\n  name: 'Some location Name'\n};\nchannelApeClient.locations().create(locationCreationRequest)\n  .then((location: Location) =\u003e {\n    // Do what you need with the created location\n  });\n```\n\n### Update Location\n```typescript\nconst locationUpdateRequest: LocationUpdateRequest = {\n  id: '123',\n  name: 'Some updated location Name'\n};\nchannelApeClient.locations().update(locationUpdateRequest)\n  .then((location: Location) =\u003e {\n    // Do what you need with the updated location\n  });\n```\n\n### Get location SLA\n```typescript\nconst locationId: string = '1';\nchannelApeClient.locations().getSLA(locationId)\n  .then((locationSLA: LocationSLA) =\u003e {\n    // Do what you need with the locations\n  });\n```\n\n### Update location SLA information\n```typescript\nconst LocationSLAUpdate: LocationSLA = {\n\tcreatedAt: '2018-04-24T14:02:34.703Z',\n\tfulfillmentSLAHours: '1',\n\tlocationId: '1',\n\toperatingDays: [\n\t\t{\n\t\t\tcreatedAt: '2018-04-24T14:02:34.703Z',\n\t\t\tday: 'T',\n\t\t\tend: '10:00',\n\t\t\tfulfillmentCutoffTime: '09:30',\n\t\t\tid: '23',\n\t\t\topen: '08:00',\n\t\t\tupdatedAt: '2018-04-24T14:02:34.703Z'\n\t\t},\n\t\t{\n\t\t\tcreatedAt: '2018-04-24T14:02:34.703Z',\n\t\t\tday: 'W',\n\t\t\tend: '10:00',\n\t\t\tfulfillmentCutoffTime: '09:50',\n\t\t\tid: '24',\n\t\t\topen: '08:00',\n\t\t\tupdatedAt: '2018-04-24T14:02:34.703Z'\n\t\t}\n\t],\n\tupdatedAt: '2018-04-24T14:02:34.703Z'\n};\nconst locationId: string = '1';\nchannelApeClient.locations().updateSla(locationId, sla)\n\t.then((locationSLA: LocationSLA) =\u003e {\n\t\t// Do what you need with the locations update\n\t});\n```\n\n### Get location closures\n```typescript\nconst locationId: string = '1';\nchannelApeClient.locations().getClosures(locationId)\n  .then((locationClosures: LocationClosedDay[]) =\u003e {\n    // Do what you need with the locations\n  });\n```\n\n### Update location closures\n```typescript\nconst closesDates: LocationClosureRequest = {\n\tclosedDays: [\n\t'2021/02/01',\n\t'2021/03/01',\n\t'2021/04/01',\n\t'2021/05/01',\n\t'2021/06/01'\n\t]\n};\nconst locationId: string = '1';\nchannelApeClient.locations().updateClosures(locationId, closedDates)\n  .then((locationClosures: LocationClosedDay[]) =\u003e {\n    // Do what you need with the locations closures update\n  });\n```\n\n### Steps\n\n#### Get step by ID\n```typescript\nchannelapeClient.steps().get(stepId)\n  .then((step: Step) =\u003e {\n    // do what you need to do with step data here\n  });\n```\n\n### Plays\n\n#### Get Play by ID\n```typescript\nchannelapeClient.plays().get(playId)\n  .then((play: Play) =\u003e {\n    // do what you need to do with play data here\n  });\n```\n#### Get All Plays\n```typescript\nchannelapeClient.plays().get()\n  .then((plays: Play[]) =\u003e {\n    // do what you need to do with all play data here\n  });\n```\n#### Get All Recipe\n```typescript\nchannelapeClient.recipes().getAll(businessId)\n  .then((recipes: Recipe[]) =\u003e {\n    //do what you need to do with all recipes data here\n  });\n```\n#### Get a Recipe\n```typescript\nchannelapeClient.recipes().get(recipeId)\n  .then((recipes: Recipe) =\u003e {\n    //do what you need to do with the recipe data here\n  });\n```\n#### Get All Schedule\n```typescript\nchannelapeClient.schedules().getAll(businessId)\n  .then((schedules: Schedule[]) =\u003e {\n    // do what you need to do with all schedules data here\n  });\n```\n#### Get a Schedule\n```typescript\nchannelapeClient.schedules().get(scheduleId)\n  .then((schedules: Schedule) =\u003e {\n    // do what you need to do with the schedule data here\n  });\n```\n\n### Batches\n#### Get a batches information\n```typescript\nchannelapeClient.batches().get(batchId)\n  .then((batch: Batch) =\u003e {\n    // do what you need to do with the batch data here\n  });\n```\n\n### Batch Inventory Quantity Adjustments (Asynchronous)\nYou can trigger a new batch by following the format below. The max number of adjustments per batch is 5000.\n\n```typescript\nconst batchRequest = BatchAdjustmentCreationRequest = {\n    businessId: '91f47fdf-fd71-484c-9b3b-db4e2877a229',\n    adjustments: [\n      {\n        locationId: '47',\n        operation: AdjustmentType.ADJUST,\n        sku: 'ABC-123',\n        memo: 'Adjusting for intraday inventory.',\n        quantity: 1,\n        inventoryStatus: InventoryStatus.AVAILABLE_TO_SELL,\n        idempotentKey: 'some-idempotent-key'\n      },\n      {\n        locationId: '12',\n        operation: AdjustmentType.SET,\n        inventoryItemId: 123,\n        memo: 'Adjusting for nightly true up.',\n        quantity: 1,\n        inventoryStatus: InventoryStatus.COMMITTED,\n        idempotentKey: 'some-idempotent-key'\n      },\n    ],\n  }\n\n  channelapeClient.batches().createInventoryAdjustmentBatch(batchRequest)\n  .then((batchResponse: BatchResponse) =\u003e {\n    // do what you need to do with the batch response here\n  });\n```\n\n#### Adjustment Expiration Date\nYou can make adjustments with an `expirationTime`,\njust provide an `expirationTime` and we'll stage an adjustment with the quantity inversed, -15 in this example, for that specific time:\n\n```typescript\nconst batchRequest = BatchAdjustmentCreationRequest = {\n    businessId: '91f47fdf-fd71-484c-9b3b-db4e2877a229',\n    adjustments: [\n      {\n        locationId: '47',\n        operation: AdjustmentType.ADJUST,\n        sku: 'ABC-123',\n        memo: 'Reserving for reason xyz.',\n        quantity: 15,\n        expirationTime: new Date('2023-12-20T12:30:00Z'),\n        inventoryStatus: InventoryStatus.RESERVE,\n        idempotentKey: 'some-idempotent-key'\n      },\n    ],\n  }\n```\n\n#### Reserve Percentage Adjustments\nYou can also make reserve adjustments based on a percentage amount by switching out `quantity` for `futureAppliedAtpPercentage` and adding an `expirationTime`:\n\n```typescript\nconst batchRequest = BatchAdjustmentCreationRequest = {\n    businessId: '91f47fdf-fd71-484c-9b3b-db4e2877a229',\n    adjustments: [\n      {\n        locationId: '47',\n        operation: AdjustmentType.ADJUST,\n        sku: 'ABC-123',\n        memo: 'Reserving for reason xyz.',\n        futureAppliedAtpPercentage: 15,\n        expirationTime: new Date('2023-12-20T12:30:00Z'),\n        inventoryStatus: InventoryStatus.RESERVE,\n        idempotentKey: 'some-idempotent-key'\n      },\n    ],\n  }\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchannelape%2Fchannelape-typescript-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchannelape%2Fchannelape-typescript-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchannelape%2Fchannelape-typescript-sdk/lists"}