Awesome-omni-skill apideck-python

Apideck Unified API integration patterns for Python. Use when building integrations with accounting software (QuickBooks, Xero, NetSuite), CRMs (Salesforce, HubSpot, Pipedrive), HRIS platforms (Workday, BambooHR), file storage (Google Drive, Dropbox, Box), ATS systems (Greenhouse, Lever), e-commerce, or any of Apideck's 200+ connectors using Python. Covers the apideck-unify SDK, authentication, CRUD operations, pagination, filtering, async support, and Vault connection management.

install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/apideck-python" ~/.claude/skills/diegosouzapw-awesome-omni-skill-apideck-python-1c05cb && rm -rf "$T"
manifest: skills/development/apideck-python/SKILL.md
source content

Apideck Python SDK Skill

Overview

The Apideck Unified API provides a single integration layer to connect with 200+ third-party services across accounting, CRM, HRIS, file storage, ATS, e-commerce, and more. The official Python SDK (

apideck-unify
) provides typed clients for all unified APIs.

Installation

pip install apideck-unify

Requires Python 3.9+. Dependencies:

httpx
,
pydantic
.

IMPORTANT RULES

  • ALWAYS use the
    apideck-unify
    SDK. DO NOT make raw
    httpx
    /
    requests
    calls to the Apideck API.
  • ALWAYS pass
    api_key
    ,
    app_id
    , and
    consumer_id
    when initializing the client.
  • ALWAYS set the
    APIDECK_API_KEY
    environment variable rather than hardcoding API keys.
  • USE
    service_id
    to specify which downstream connector to use (e.g.,
    "salesforce"
    ,
    "quickbooks"
    ). If a consumer has multiple connections for an API,
    service_id
    is required.
  • USE context managers (
    with
    /
    async with
    ) for client lifecycle management.
  • USE the
    fields
    parameter to request only the columns you need.
  • USE the
    filter_
    parameter (note the trailing underscore) to narrow results server-side.
  • ALWAYS handle errors with try/except using
    models.ApideckError
    as the base class.

Quick Start

from apideck_unify import Apideck
import os

with Apideck(
    api_key=os.getenv("APIDECK_API_KEY", ""),
    app_id="your-app-id",
    consumer_id="your-consumer-id",
) as apideck:
    res = apideck.crm.contacts.list(
        service_id="salesforce",
        limit=20,
        filter_={"email": "john@example.com"},
    )
    while res is not None:
        for contact in res.data:
            print(contact.name, contact.emails)
        res = res.next()

SDK Patterns

Client Setup

from apideck_unify import Apideck
import os

with Apideck(
    api_key=os.getenv("APIDECK_API_KEY", ""),
    app_id="your-app-id",
    consumer_id="your-consumer-id",
) as apideck:
    # Make API calls here
    pass

The

consumer_id
identifies the end-user whose connections are being used. In multi-tenant apps, set this per-request or per-user session.

CRUD Operations

All resources follow the same pattern:

apideck.{api}.{resource}.{operation}()
.

import apideck_unify
from apideck_unify import Apideck
import os

with Apideck(
    api_key=os.getenv("APIDECK_API_KEY", ""),
    app_id="your-app-id",
    consumer_id="your-consumer-id",
) as apideck:

    # LIST - retrieve multiple records
    res = apideck.crm.contacts.list(
        service_id="salesforce",
        limit=20,
        filter_={"email": "john@example.com", "company_id": "12345"},
        sort={"by": apideck_unify.ContactsSortBy.CREATED_AT, "direction": apideck_unify.SortDirection.DESC},
        fields="id,name,email",
    )

    # CREATE - create a new record
    res = apideck.crm.contacts.create(
        service_id="salesforce",
        first_name="John",
        last_name="Doe",
        emails=[{"email": "john@example.com", "type": apideck_unify.EmailType.PRIMARY}],
        phone_numbers=[{"number": "+1234567890", "type": apideck_unify.PhoneNumberType.PRIMARY}],
    )
    print(res.create_contact_response)

    # GET - retrieve a single record
    res = apideck.crm.contacts.get(id="contact_123", service_id="salesforce")

    # UPDATE - modify an existing record
    res = apideck.crm.contacts.update(id="contact_123", service_id="salesforce", first_name="Jane")

    # DELETE - remove a record
    res = apideck.crm.contacts.delete(id="contact_123", service_id="salesforce")

Pagination

Use the

.next()
method on response objects for cursor-based pagination:

res = apideck.accounting.invoices.list(service_id="quickbooks", limit=50)

while res is not None:
    for invoice in res.data:
        print(invoice.number, invoice.total)
    res = res.next()

Async Support

Every sync method has an

_async
counterpart. Use
async with
as context manager:

import asyncio
from apideck_unify import Apideck
import os

async def main():
    async with Apideck(
        api_key=os.getenv("APIDECK_API_KEY", ""),
        app_id="your-app-id",
        consumer_id="your-consumer-id",
    ) as apideck:
        res = await apideck.crm.contacts.list_async(
            service_id="salesforce",
            limit=20,
        )
        while res is not None:
            for contact in res.data:
                print(contact.name)
            res = res.next()

asyncio.run(main())

Error Handling

from apideck_unify import Apideck, models

try:
    res = apideck.crm.contacts.get(id="invalid", service_id="salesforce")
except models.BadRequestResponse as e:
    print("Bad request:", e.message, e.status_code)
except models.UnauthorizedResponse as e:
    print("Invalid API key or missing credentials")
except models.NotFoundResponse as e:
    print("Record not found")
except models.PaymentRequiredResponse as e:
    print("API limit reached")
except models.UnprocessableResponse as e:
    print("Validation error:", e.message)
except models.ApideckError as e:
    print(f"API error {e.status_code}: {e.message}")

All exceptions inherit from

models.ApideckError
with properties:
message
,
status_code
,
headers
,
body
,
raw_response
.

Common Parameters

ParameterTypeDescription
service_id
str
Downstream connector ID (e.g.,
"quickbooks"
,
"salesforce"
)
limit
int
Max results per page (1-200, default 20)
cursor
str
Pagination cursor from previous response
filter_
dict
Resource-specific filter criteria (note trailing underscore)
sort
dict
{"by": SortField, "direction": SortDirection}
fields
str
Comma-separated field names to return
pass_through
dict
Pass-through query parameters for the downstream API
raw
bool
Include raw downstream response when
True
retry_config
RetryConfig
Per-call retry override

Pass-Through Parameters

# Query pass-through
res = apideck.accounting.invoices.list(
    service_id="quickbooks",
    pass_through={"search": "overdue"},
)

# Body pass-through for connector-specific fields
res = apideck.crm.contacts.create(
    service_id="salesforce",
    first_name="John",
    last_name="Doe",
    pass_through=[{
        "service_id": "salesforce",
        "operation_id": "contactsAdd",
        "extend_object": {"custom_sf_field__c": "value"},
    }],
)

Retry Configuration

from apideck_unify import Apideck
from apideck_unify.utils import BackoffStrategy, RetryConfig

with Apideck(
    api_key=os.getenv("APIDECK_API_KEY", ""),
    app_id="your-app-id",
    consumer_id="your-consumer-id",
    retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False),
) as apideck:
    pass

API Namespaces

NamespaceResources
apideck.accounting.*
invoices, bills, payments, customers, suppliers, ledger_accounts, journal_entries, tax_rates, credit_notes, purchase_orders, balance_sheet, profit_and_loss, expenses, attachments, and more
apideck.crm.*
contacts, companies, leads, opportunities, activities, notes, pipelines, users
apideck.hris.*
employees, companies, departments, payrolls, time_off_requests
apideck.file_storage.*
files, folders, drives, shared_links, upload_sessions
apideck.ats.*
applicants, applications, jobs
apideck.vault.*
connections, consumers, sessions, custom_mappings, logs
apideck.webhook.*
webhooks, event_logs