install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/brokenwatch24/jobtread-api" ~/.claude/skills/openclaw-skills-jobtread-api && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/brokenwatch24/jobtread-api" ~/.openclaw/skills/openclaw-skills-jobtread-api && rm -rf "$T"
manifest:
skills/brokenwatch24/jobtread-api/SKILL.mdsource content
Skill: JobTread via Pave Query API
Summary
This skill lets you operate JobTread entirely through openclaw using the Pave-based API at
https://api.jobtread.com/pave. Every request is a single POST with a query object that mirrors GraphQL-style expressions, and you decide which fields you want back. With the right grant key, you can create and manage accounts (customers/vendors), jobs, documents, tasks, locations, custom fields, documents, and even subscribe to webhooks for live updates.
Setup & Credentials
- Create a grant: Login to https://app.jobtread.com/grants and create a new grant for automation. Copy the one-time
(it begins withgrantKey
and will only show once).grant_ - Store the key locally: Use a secure file such as
. Example:~/.config/jobtread/grant_keymkdir -p ~/.config/jobtread echo "grant_xxx" > ~/.config/jobtread/grant_key chmod 600 ~/.config/jobtread/grant_key - Keep it fresh: JobTread expires keys after 3 months of inactivity, so schedule a reminder (cron/heartbeat) to rotate or re-use the grant before expiration.
- Optional webhook secret: If you plan to receive webhooks, note your endpoint URL and save the webhook ID in the same folder so you can disable or inspect it later.
Authentication
- Every POST to
must include the grant key under/pave
. Example payload:query.$.grantKey{ "query": { "$": { "grantKey": "grant_xxx" }, "currentGrant": { "id": {}, "user": { "name": {} } } } } - You can also set
,notify
, ortimeZone
insideviaUserId
when you need to suppress notifications or scope results.$ - For signed queries (PDF tokens, pre-signed data), call
and append the token topdfToken: { _: signQuery, $: { query: {...} } }
.https://api.jobtread.com/t/
API Basics & Request Flow
- All requests go to
withPOST https://api.jobtread.com/pave
.Content-Type: application/json - Structure:
{ "query": { "$": { "grantKey": "grant_xxx" }, "operation": { "$": { ...inputs... }, "field": { ...fields... } } } } - Fields you request (
,id
, etc.) determine what JobTread returns. Always includename
when you plan to reference the object later.id
in responses tells you the schema for that node._type
Common Patterns & Examples
1. Discover your organization ID
currentGrant: user: memberships: nodes: organization: id: {} name: {}
Use the returned
organization.id in any following query.
2. Create customers/vendors
- Customer
createAccount: $: name: "Test Customer" type: customer organizationId: "ORG_ID" createdAccount: id: {} name: {} type: {}
- Vendor (same as above but
).type: vendor
3. Read or update accounts
- Read account by supplying
and requesting fields:id
account: $: id: "ACCOUNT_ID" id: {} name: {} isTaxable: {}
- Update and include
if needed:customFieldValues
updateAccount: $: id: "ACCOUNT_ID" isTaxable: false account: id: {} isTaxable: {}
4. Query accounts list with pagination, sorting, and filters
organization: $: {} id: {} accounts: $: size: 5 page: "1" sortBy: - field: type order: desc where: and: - - type - = - customer - - name - = - "Sebas Clients" nextPage: {} nodes: id: {} name: {} type: {}
5. Use where
with or
, nested fields, or custom fields
whereor- Find account by custom field name:
organization: $: {} id: {} contacts: $: with: cf: _: customFieldValues $: where: - - customField - name - "VIP" values: $: field: value where: - - cf - values - = - "Yes" nodes: id: {} name: {}
6. Locations and nested filters
Create location and find others tied to the same account:
createLocation: $: accountId: "ACCOUNT_ID" name: Test Location address: "123 Main St" createdLocation: id: {} name: {} organization: $: {} id: {} locations: $: where: - - account - name - Test Name nodes: id: {} name: {} account: id: {} name: {}
7. Documents, jobs, and aggregates
- Get a job's documents grouped by type/status and sums:
job: $: id: "JOB_ID" documents: $: where: - - type - in - - customerInvoice - customerOrder group: by: - type - status aggs: amountPaid: sum: amountPaid priceWithTax: sum: priceWithTax withValues: {}
- Get document PDF token (append to
):https://api.jobtread.com/t/{{token}}
pdfToken: _: signQuery $: query: pdf: $: id: "DOCUMENT_ID"
8. Custom fields
- Read a record's custom field values (limit 25 per request):
account: $: id: "ACCOUNT_ID" customFieldValues: $: size: 25 nodes: id: {} value: {} customField: id: {}
- Update a custom field via
map:customFieldValues
updateAccount: $: id: "ACCOUNT_ID" customFieldValues: "CUSTOM_FIELD_ID": "New value" account: id: {}
9. Webhooks
- Use the JobTread UI to create a webhook (Webhooks page) and copy its ID.
- Manage them via the API: list
orwebhook(id: "ID")
to cancel.deleteWebhook - Example create query:
createWebhook: $: organizationId: "ORG_ID" url: "https://your-endpoint/hooks/jobtread" eventTypes: - jobCreated - documentUploaded createdWebhook: id: {} url: {}
Using This Skill with OpenClaw
- Use
or your preferred HTTP client from OpenClaw'scurl
tool.exec - Build the JSON payload as shown (always include the grant key inside
).$ - You can also wrap the payload in shell variables or helper scripts for portability.
- Save reusable queries in the skill file or separate scripts so Claude or you can call them by name ("run job summary", "create customer", etc.).
- Document each automation in the JobTread vault so you can copy/paste from future sessions without digging through logs.
Automation Ideas
- Nightly job summary: Query each open job, sum approved customer orders, and store results in Obsidian (or send via WhatsApp).
- Webhook monitor: Automatically spin up a webhook for file uploads and forward notifications to your Slack/WhatsApp via a small server.
- Batch account creation: Feed a CSV of customers/vendors and run
for each with the same grant key.createAccount - Document check-ins: Query documents with
and send you a summary each morning.status: pending
Troubleshooting & Tips
- Rate limits: Grant keys have a throughput cap. If you hit rate limits, add
between requests or batch fewer objects.time.sleep - Missing IDs: The API complains
when you forget to requestid field required
. Always include it when you plan to mutate the record later.id - Grant expiration: If a request returns
, rotate the grant and updateinvalid key
.~/.config/jobtread/grant_key - Webhooks: Keep a log of webhook IDs so you can disable or reconfigure them later.
- Signed tokens: Use
when you need temporary access to document PDFs without storing raw document IDs.signQuery