Authentication and Scopes

All Presscart API traffic uses bearer-token auth. pypresscart handles the header automatically — you just pass the token to the client.

client = PresscartClient(api_token="pc_...")

The library sets:

Authorization: Bearer pc_...
Accept: application/json
User-Agent: pypresscart/<version>

You can override the User-Agent via PresscartClient(..., user_agent="my-app/1.0"). See Client Configuration.

Getting a token

API tokens are issued by Presscart to partners with an active agreement — they aren’t self-serve through the dashboard. If you don’t have one yet, reach out to Presscart to start the partner onboarding process.

Once issued:

  • Tokens start with pc_.

  • The raw value is only shown once, at issuance. Keep it somewhere safe (a secret manager, .env file excluded from version control, etc.).

  • Never hardcode a token into source you publish. If a token leaks, contact Presscart to rotate it.

Token types

Type

Behavior

full_access

Bypasses scope checks. Can call any API-token route.

custom

Only the explicit scopes on the token. Most common.

read_only

Can GET/LIST on its scopes but cannot write.

client.auth.whoami() returns the current token’s type in .token_type. See Auth.

Scopes

Scopes gate endpoint access. If a call returns HTTP 403, the token is valid but missing the scope — pypresscart raises PermissionError. See Error Handling.

Scope

Routes

outlets.lists

GET /outlets

outlets.read

GET /outlets/{outlet_id}, GET /outlets/{id}/products, GET /outlets/locations/*

tags.lists

GET /tags

outlet_disclaimers.lists

GET /outlet-disclaimers

products.read

GET /products/{product_id}, GET /products/listings, GET /products/categories

orders.lists

GET /orders, GET /order-items, GET /profiles/{id}/orders, GET /profiles/{id}/order-items

orders.read

GET /orders/{order_id}

orders.create

POST /orders/checkout

profiles.lists

GET /teams/{team_id}/profiles

campaigns.lists

GET /campaigns, GET /profiles/{id}/campaigns

campaigns.read

GET /campaigns/{id}, GET /campaigns/{id}/articles, GET /campaigns/{id}/articles/status-count

campaigns.create

POST /campaigns

campaigns.update

PUT /campaigns/{id}, POST /campaigns/{id}/order-items, POST /questionnaires/{id}/link

files.lists

GET /files

files.read

GET /files/{id}, GET /files/{id}/download

files.create

POST /files/upload

files.update

POST /files/move

files.delete

DELETE /files/{id}

folders.lists

GET /folders

folders.create

POST /folders

folders.update

PATCH /folders/{id}

folders.delete

DELETE /folders/{id}

Every resource method in pypresscart documents its required scope in the docstring:

help(client.campaigns.create)
# Create a campaign. Required scope: `campaigns.create`.

Defensive checks

Verify scopes before launching a workflow:

REQUIRED = {"outlets.lists", "orders.create", "campaigns.update"}

info = client.auth.whoami()
missing = REQUIRED - set(info.scopes)
if info.token_type != "full_access" and missing:
    raise RuntimeError(f"token is missing scopes: {sorted(missing)}")

Rotation

When you rotate a token, instantiate a new client. Tokens aren’t mutable on an existing PresscartClient.

client = PresscartClient(api_token=new_token)

Environment loading

A common pattern:

import os
from pypresscart import PresscartClient

token = os.environ.get("PRESSCART_API_TOKEN")
if not token:
    raise SystemExit("PRESSCART_API_TOKEN is not set")

client = PresscartClient(api_token=token)

For .env files, use python-dotenv and call load_dotenv() before instantiating the client.