Site Logo

Get started with Elements

ShipEngine Elements can be integrated into your application in two ways: as an SDK or as a suite of React components.

Regardless of the integration method you choose, you'll need to generate a ShipEngine Platform token and establish a new ShipEngine Partner account.

To learn more about ShipEngine Platform tokens, refer to the Platform token documentation. For more information about ShipEngine Partner accounts, visit the Partners API documentation.

The code presented in this video is from a previous version of Elements. Use the code samples provided in the Elements SDK or React Components sections for the current version.

Step 1: Creating a ShipEngine Account

To create a ShipEngine Elements JWT, a ShipEngine Account ID (also known as a ShipEngine Seller ID or tenant in some cases) is required. To make a new ShipEngine Seller, run the following curl request. To learn more about creating ShipEngine accounts, check out the ShipEngine account documentation.

1
2
3
4
5
6
7
8
9
10
curl --location --request POST 'https://api.shipengine.com/v1/partners/accounts' \
--header 'api-key: [my-api-key]' \
--header 'Content-Type: application/json' \
--header 'partner-id: [my-partner-id]' \
--data-raw '{
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp.",
"origin_country_code": "US"
}'

You will use the account_id field on the ShipEngine account creation response that the above curl request to sign a ShipEngine Elements JWT.

1
2
3
4
5
6
7
8
9
10
11
{
"api_key": {
"encrypted_api_key": "[another-api-key]",
...
},
"account_id": 1234567, # seller id needed to sign JWT
"external_account_id": null,
"created_at": "2023-03-12T15:02:26.523Z",
"modified_at": "2023-03-12T15:02:26.523Z",
...
}

Step 2: Signing your JWT

The following pieces of information are required to sign ShipEngine Platform JWT.

  1. ShipEngine Partner ID: You should have received this after you had completed partner onboarding with your ShipEngine technical contact. This is a unique identifier for your ShipEngine Partner account.
  2. Tenant ID: The ID of the ShipEngine account that was created. This is also known as the ShipEngine Seller ID you may have been given during partner onboarding.
  3. Public/Private RSA keys: You should have registered the public key with ShipEngine during partner onboarding. We recommend you store the private RSA key you created in a secure container format, like .pem.
  4. Platform Token Key ID: You should have received this after you had completed partner onboarding with your ShipEngine technical contact. This will be the name of the platform token key you registered with ShipEngine during partner onboarding.
  5. Scope: You should have received this after you had completed partner onboarding with your ShipEngine technical contact. The scope enforces the usage of a specific subset of ShipEngine API endpoints.
  6. Platform Token Issuer: You should have received this after you had completed partner onboarding with your ShipEngine technical contact.

The following is an example of one possible way of generating a ShipEngine Platform JWT. Keep in mind, the same sample JWT application we mentioned earlier can be used to sign your JWT's.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import fs from 'fs';
import jsonwebtoken from 'jsonwebtoken';
import express from 'express';
import cors from 'cors';
import 'dotenv/config';
const app = express();
app.use(cors());
const generateToken = async () => {
const payload = {
partner: process.env.SHIPENGINE_PARTNER_ID,
tenant: process.env.SHIPENGINE_SELLER_ID, // The ShipEngine Seller ID you created
scope: process.env.SCOPE,
};
const secretKey = fs.readFileSync('certs/private.pem', 'utf-8');
if (!secretKey) throw new Error('Missing secret key');
const token = await jsonwebtoken.sign(payload, secretKey, {
algorithm: 'RS256',
expiresIn: 3600,
issuer: process.env.PLATFORM_TOKEN_ISSUER,
keyid: process.env.PLATFORM_TOKEN_KEY_ID,
});
return token;
};
app.get('/generate-token', async (_req, res) => {
const token = await generateToken();
res.status(200).json({ token });
});
app.listen(3002, () => {
console.log('Server listening on port 3002');
});

Step 3: Using Elements

Determine your preferred integration method:

If you're just getting started with ShipEngine Elements, it's helpful to know that by default, a ShipEngine Seller does not have warehouses (ship from locations) or carriers (USPS, UPS, DHL Express) attached to the seller account. These are required to purchase a label.

We recommend starting your users (ShipEngine Sellers) with the onboarding workflow via the Onboarding Element to set up their warehouse and carrier accounts.

Updates to warehouse and carrier accounts created during onboarding can be made through the Account Settings Element.

Connecting Carrier Accounts

Elements integrates with the leading global shipping carriers. Check out the complete carriers documentation to learn more about ShipEngine carriers.

To enable ShipEngine carrier accounts, you must explicitly list them in the globalFeatures.enabledShipEngineCarriers array within the features prop when initializing Elements.

Supported ShipEngine Carriers

Supported External Carriers

To enable external carrier connections, you must explicitly list them in the globalFeatures.enabledExternalCarriers array within the features prop when initializing Elements. To learn more about connecting your external carriers checkout the Connect External Carrier Element.

For an in depth overview of the global features object, please review the Configuring Elements Features step in either the ElementsProvider or the Elements SDK guides.

Migration Guide to Elements v2

1. ShipEngine Alchemy is no longer a required package

To better address our partner's bundle size requirements in their applications, we have removed the need for the @shipengine/alchemy package. The core functionality of @shipengine/alchemy has been baked into the @shipengine/elements package. Similarly rather than wrapping your app in the <AlchemyProvider/> in v2, we have exposed the new <ElementsProvider/>.

To learn more about getting started with the Elements React components, check out the Elements React Components documentation.

2. Elements name changes

Some of the Elements names have be changed to better align the Elements with proper naming conventions.

v1 Namev2 Name
ManageWalletWorkflowCarrierServices
ShipEngineCarriersManageCarriers
ConnectCarrierConnectExternalCarrier
ExternalCarriersManageExternalCarriers
WalletHistoryTransactionHistory
PurchaseLabelWorkflowLabelWorkflow
ViewShipmentShipmentSummary

3. Features added to the Elements Provider and Elements SDK constructor

To improve the developer experience while implementing Elements, we have added a features prop to the Elements Provider and a features parameter to the Elements SDK constructor. In essence, this new features object rolls all the features throughout the Elements project into one object. For organizational purposes, we nested each Element's features under the Element's respective key within the object.

Features used throughout the Elements project, especially those pertaining to carriers like enabledShipEngineCarriers were hoisted up to a global features object shared throughout the project.

Any Element, in v1, whose only features are related to carriers i.e. enabledShipEngineCarriers or enabledExternalCarriers, have been moved up to the global features context. Below is the list of Elements which were affected by this change.

We recommend configuring the features you want to use in the Elements Provider or the SDK constructor for the Element. However, if you need to override features for a specific Element, you can use the feature prop for that Element, provided the Element supports it.

Learn more about each elements respective features.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const elementsFeatures = {
globalFeatures: {
// Available external carrier codes for external carriers you wish to enable.
// ! NOTE: If this feature is omitted, external carrier accounts will not be available to connect.
enabledExternalCarriers: [
'apc',
'asendia',
'better_trucks',
'courierpost',
'dpd',
'seko',
'ups',
'yodel',
],
// Available ShipEngine carrier codes for carriers you wish to enable.
// ! NOTE: If this feature is omitted, ShipEngine carrier accounts will not be available to connect.
enabledShipEngineCarriers: ['ups', 'stamps_com'],
// Enables the `Powered by ShipEngine` logo in the footer of various Elements.
poweredByShipEngine: false,
},
purchaseLabelFeatures: { ... },
shipmentSummaryFeatures: { ... },
accountSettingsFeatures: { ... },
labelsGridFeatures: { ... }
}
// Create a new instance of the Elements SDK with features.
const elements = new ElementsSDK(
getToken,
{
onError: (err: Error) => console.error(err),
baseURL: 'https://elements.shipengine.com',
themeConfig: themeConfig,
locale: 'en-US',
features: elementsFeatures
}
);

4. Elements SDK improvements

In a effort to more closely align the Elements SDK with the functionality provided by the Element React components, we have made significant improvement to the Elements SDK.

Mount Elements anywhere in the DOM

Using the new create method on the Elements SDK class, you can now pass an HTML ID attribute or HTML element to the mount method to mount any Elements anywhere in your application HTML document. See here to learn more about mounting Elements.

Rendering in a Side Panel

Methods like elements.onboardUser or elements.purchaseLabel, accessible via the Elements SDK class, have been deprecated in Elements v2 and will be removed in future versions. We have replaced these methods with the renderSidePanel method, which is available in the returned object via the create method. Please follow the recommended workflow in the Elements Render Methods section to render elements in a Side Panel.

If you wish to temporarily continue using these methods, the parameter signatures have changed from v1, and will need to be updated. Rather than passing three parameters for Element properties, side panel properties, and header properties respectively, the methods take a single object argument with these values as properties:

1
2
3
4
5
// Version 1 method invocation...
elements.purchaseLabel(props, panelProps, headerProps);
// ...becomes in version 2
elements.purchaseLabel({ elementProps: props, sidePanelProps: panelProps, sidePanelHeaderProps: headerProps });

Furthermore, some of the method names have been updated to correspond with the updated Element names. All others remain the same:

v1 Namev2 Name
purchaseLabelWorkflowlabelWorkflow
viewShipmentshipmentSummary

Destroy method

In v1 of the Elements SDK, the unmount method, available via the SDK class, removed the React root and the HTML element to which the SDK attached the side panel. This method has been renamed destroy.