Carrier accounts
Choose which carriers (paqueterías) and services quote for your organization, and connect your own negotiated carrier contract.
Your organization decides which carriers take part in each quote, and with which services. You can also connect your own carrier contract with DHL, FedEx, or Estafeta. The carrier then bills you for freight directly, and SendIt charges only a per-label fee.
| Method | Path | Scope | Description |
|---|---|---|---|
GET |
/v1/carrier-preferences |
— | List every carrier with your organization’s configuration |
GET |
/v1/carrier-preferences/:carrierCode |
— | Get one carrier |
PUT |
/v1/carrier-preferences/:carrierCode |
carrier_preferences:write |
Update one carrier |
PATCH |
/v1/carrier-preferences/bulk |
carrier_preferences:write |
Enable or disable several at once |
DELETE |
/v1/carrier-preferences/:carrierCode |
carrier_preferences:write |
Reset one carrier to its defaults |
PUT |
/v1/carrier-preferences/:carrierCode/credentials |
carrier_preferences:write |
Store your own account’s credentials |
DELETE |
/v1/carrier-preferences/:carrierCode/credentials |
carrier_preferences:write |
Clear the credentials and return to SendIt’s account |
POST |
/v1/carrier-preferences/:carrierCode/credentials/verify |
carrier_preferences:write |
Verify the stored credentials |
Write endpoints require the ADMIN role or above.
Check your configuration
curl https://api.sendit.mx/v1/carrier-preferences \
-H "X-API-Key: sk_test_..."
{
"success": true,
"data": [
{
"carrierCode": "FEDEX",
"carrierName": "FedEx",
"availableServices": [
{ "serviceName": "FedEx Economy", "serviceLevel": "economy" },
{ "serviceName": "FedEx Express", "serviceLevel": "express" }
],
"supportsPickups": true,
"isConfigured": true,
"isEnabled": true,
"enabledServices": ["economy", "express"],
"defaultService": "express",
"usesOwnAccount": false
}
],
"meta": { "count": 1 }
}
| Field | Description |
|---|---|
availableServices |
The services the carrier offers, with their serviceLevel |
supportsPickups |
Whether it accepts scheduled pickups |
isConfigured |
Whether your organization has saved its own configuration for this carrier |
isEnabled |
Whether it takes part in POST /v1/rates |
enabledServices |
Allowed services; null = all of them |
defaultService |
Pre-selected service in your forms (convenience only) |
usesOwnAccount |
Whether quotes and labels use your own carrier account |
GET /v1/carrier-preferences/:carrierCode returns a single object with the same shape.
Choose which carriers quote
Body parameters
isEnabled?boolean
Whether the carrier takes part in POST /v1/rates.
booleanenabledServices?array
Allowed services (serviceLevel). Each entry must exist in that carrier's availableServices. null = all of them.
arraydefaultService?string
Pre-selected service. Must exist in that carrier's availableServices.
stringcurl -X PUT https://api.sendit.mx/v1/carrier-preferences/FEDEX \
-H "X-API-Key: sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"isEnabled": true,
"enabledServices": ["express", "overnight"],
"defaultService": "express"
}'
The response is the updated carrier object.
To flip several at once, send the complete list of the ones you want enabled. Anything absent is disabled:
curl -X PATCH https://api.sendit.mx/v1/carrier-preferences/bulk \
-H "X-API-Key: sk_test_..." \
-H "Content-Type: application/json" \
-d '{ "enabledCarriers": ["FEDEX", "DHL", "ESTAFETA"] }'
{
"success": true,
"data": {
"enabled": ["FEDEX", "DHL", "ESTAFETA"],
"disabled": ["SENDEX", "AMPM"]
}
}
DELETE /v1/carrier-preferences/FEDEX resets that carrier (204, no body): back to isEnabled: true, enabledServices: null, defaultService: null, and it clears your own credentials if any were stored.
| Code | When | How to resolve it |
|---|---|---|
400 INVALID_INPUT |
enabledServices or defaultService names a service that carrier doesn’t offer |
Use a serviceLevel from its availableServices |
403 INSUFFICIENT_SCOPE |
The key lacks carrier_preferences:write |
Issue a key with that scope |
404 RESOURCE_NOT_FOUND |
The carrierCode isn’t in the catalog |
Check the carrier catalog |
How this affects your quotes
| Endpoint | Honors isEnabled |
Honors enabledServices |
|---|---|---|
POST /v1/rates |
Yes | Yes |
POST /v1/rates/carrier/:carrierCode |
No — asking for a carrier explicitly bypasses the toggle | Yes |
That lets you offer a carrier-specific quoting flow without losing the service restrictions you configured.
Use your own carrier account
If you have a negotiated contract with DHL, FedEx, or Estafeta, store those credentials and SendIt will quote and buy with them. The carrier bills the freight to you, under your contract; SendIt charges only a per-label fee.
Body parameters
accountNumber?string
The account number the carrier issued you.
stringapiKey?string
API key issued by the carrier.
stringapiSecret?string
API secret issued by the carrier.
stringmeta?object
Extra fields that specific carrier requires (for example meterNumber).
objectSend at least one of the four.
curl -X PUT https://api.sendit.mx/v1/carrier-preferences/FEDEX/credentials \
-H "X-API-Key: sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"accountNumber": "123456789",
"apiKey": "carrier-issued-key",
"apiSecret": "carrier-issued-secret",
"meta": { "meterNumber": "987654" }
}'
The response is the normal carrier object, now with usesOwnAccount: true:
{
"success": true,
"data": {
"carrierCode": "FEDEX",
"carrierName": "FedEx",
"isConfigured": true,
"isEnabled": true,
"enabledServices": null,
"defaultService": null,
"usesOwnAccount": true
}
}
The response never echoes the credentials you sent. Do not keep them in frontend state or write them to logs after submitting them.
Verify and clear
curl -X POST https://api.sendit.mx/v1/carrier-preferences/FEDEX/credentials/verify \
-H "X-API-Key: sk_test_..."
{
"success": true,
"data": { "carrierCode": "FEDEX", "valid": true }
}
DELETE /v1/carrier-preferences/FEDEX/credentials clears the credentials and returns the object with usesOwnAccount: false; from then on quotes use SendIt’s account again.
| Code | When | How to resolve it |
|---|---|---|
400 INVALID_INPUT |
You sent none of the four fields | Include at least accountNumber, apiKey, apiSecret, or meta |
403 INSUFFICIENT_SCOPE |
The key lacks carrier_preferences:write |
Issue a key with that scope |
404 RESOURCE_NOT_FOUND |
The carrierCode doesn’t exist, or there are no stored credentials to verify or clear |
Store the credentials first with PUT |
What changes in the quote
A quote made with your own account carries two extra fields:
{
"carrierCode": "FEDEX",
"serviceLevel": "express",
"totalPrice": 1.39,
"currency": "MXN",
"usesOwnAccount": true,
"carrierChargeEstimate": 287.43,
"breakdown": {
"baseRate": 1.20,
"fuelSurcharge": 0.00,
"insuranceCost": 0.00,
"subtotal": 1.20,
"ivaRate": 0.16,
"ivaAmount": 0.19,
"total": 1.39
}
}
totalPriceis what SendIt charges you: your plan’s per-label fee plus IVA. It’s exactly what gets debited from your wallet (monedero) when you buy the label, not a peso more.carrierChargeEstimateis the freight estimate from your own contract. It’s informational: it never enters SendIt’s wallet or your CFDI, because the carrier invoices it to you separately. It may differ from the final invoice if the carrier applies adjustments.usesOwnAccount: truemarks those semantics. Quotes on SendIt’s account carry neither field and are unchanged.
Display them separately in your UI: SendIt’s charge and the carrier’s estimated charge are two different things.
Per-label fee
| Plan | Fee per label on your own account (before IVA) |
|---|---|
| Free | $1.20 MXN |
| Growth | $0.90 MXN |
| Scale | $0.60 MXN |
| Enterprise | $0.00 MXN |
This fee replaces the normal label price, and the plan overage is not added on top: it is SendIt’s only charge for that label. The label still counts toward your monthly usage. On Enterprise the fee is zero, so no wallet movement is generated, but the label is still created and counted.
Rules when switching accounts
- Re-quote after storing or clearing credentials. Earlier quotes describe the earlier account and no longer apply.
- To void a label you bought on your own account, you need usable credentials for that carrier. If you cleared or rotated them, store them again before requesting the refund.
- Insurance on a label bought with your account is covered and billed by your carrier, not by SendIt.