{
  "schemaVersion": "1.0",
  "item": {
    "slug": "jobtread-api",
    "name": "JobTread Agent",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/Brokenwatch24/jobtread-api",
    "canonicalUrl": "https://clawhub.ai/Brokenwatch24/jobtread-api",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/jobtread-api",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=jobtread-api",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/jobtread-api"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/jobtread-api",
    "agentPageUrl": "https://openagent3.xyz/skills/jobtread-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/jobtread-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/jobtread-api/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Summary",
        "body": "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."
      },
      {
        "title": "Setup & Credentials",
        "body": "Create a grant: Login to https://app.jobtread.com/grants and create a new grant for automation. Copy the one-time grantKey (it begins with grant_ and will only show once).\nStore the key locally: Use a secure file such as ~/.config/jobtread/grant_key. Example:\nmkdir -p ~/.config/jobtread\necho \"grant_xxx\" > ~/.config/jobtread/grant_key\nchmod 600 ~/.config/jobtread/grant_key\n\n\nKeep 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.\nOptional 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."
      },
      {
        "title": "Authentication",
        "body": "Every POST to /pave must include the grant key under query.$.grantKey. Example payload:\n{\n  \"query\": {\n    \"$\": { \"grantKey\": \"grant_xxx\" },\n    \"currentGrant\": { \"id\": {}, \"user\": { \"name\": {} } }\n  }\n}\n\n\nYou can also set notify, timeZone, or viaUserId inside $ when you need to suppress notifications or scope results.\nFor signed queries (PDF tokens, pre-signed data), call pdfToken: { _: signQuery, $: { query: {...} } } and append the token to https://api.jobtread.com/t/."
      },
      {
        "title": "API Basics & Request Flow",
        "body": "All requests go to POST https://api.jobtread.com/pave with Content-Type: application/json.\nStructure:\n{\n  \"query\": {\n    \"$\": { \"grantKey\": \"grant_xxx\" },  \n    \"operation\": {\n      \"$\": { ...inputs... },\n      \"field\": { ...fields... }\n    }\n  }\n}\n\n\nFields you request (id, name, etc.) determine what JobTread returns. Always include id when you plan to reference the object later.\n_type in responses tells you the schema for that node."
      },
      {
        "title": "1. Discover your organization ID",
        "body": "currentGrant:\n  user:\n    memberships:\n      nodes:\n        organization:\n          id: {}\n          name: {}\n\nUse the returned organization.id in any following query."
      },
      {
        "title": "2. Create customers/vendors",
        "body": "Customer\n\ncreateAccount:\n  $:\n    name: \"Test Customer\"\n    type: customer\n    organizationId: \"ORG_ID\"\n  createdAccount:\n    id: {}\n    name: {}\n    type: {}\n\nVendor (same as above but type: vendor)."
      },
      {
        "title": "3. Read or update accounts",
        "body": "Read account by supplying id and requesting fields:\n\naccount:\n  $:\n    id: \"ACCOUNT_ID\"\n  id: {}\n  name: {}\n  isTaxable: {}\n\nUpdate and include customFieldValues if needed:\n\nupdateAccount:\n  $:\n    id: \"ACCOUNT_ID\"\n    isTaxable: false\n  account:\n    id: {}\n    isTaxable: {}"
      },
      {
        "title": "4. Query accounts list with pagination, sorting, and filters",
        "body": "organization:\n  $: {}\n  id: {}\n  accounts:\n    $:\n      size: 5\n      page: \"1\"\n      sortBy:\n        - field: type\n          order: desc\n      where:\n        and:\n          - - type\n            - =\n            - customer\n          - - name\n            - =\n            - \"Sebas Clients\"\n    nextPage: {}\n    nodes:\n      id: {}\n      name: {}\n      type: {}"
      },
      {
        "title": "5. Use where with or, nested fields, or custom fields",
        "body": "Find account by custom field name:\n\norganization:\n  $: {}\n  id: {}\n  contacts:\n    $:\n      with:\n        cf:\n          _: customFieldValues\n          $:\n            where:\n              - - customField\n                - name\n              - \"VIP\"\n            values:\n              $:\n                field: value\n      where:\n        - - cf\n          - values\n        - =\n        - \"Yes\"\n    nodes:\n      id: {}\n      name: {}"
      },
      {
        "title": "6. Locations and nested filters",
        "body": "Create location and find others tied to the same account:\n\ncreateLocation:\n  $:\n    accountId: \"ACCOUNT_ID\"\n    name: Test Location\n    address: \"123 Main St\"\n  createdLocation:\n    id: {}\n    name: {}\n\norganization:\n  $: {}\n  id: {}\n  locations:\n    $:\n      where:\n        - - account\n          - name\n        - Test Name\n    nodes:\n      id: {}\n      name: {}\n      account:\n        id: {}\n        name: {}"
      },
      {
        "title": "7. Documents, jobs, and aggregates",
        "body": "Get a job's documents grouped by type/status and sums:\n\njob:\n  $:\n    id: \"JOB_ID\"\n  documents:\n    $:\n      where:\n        - - type\n          - in\n          - - customerInvoice\n            - customerOrder\n      group:\n        by:\n          - type\n          - status\n        aggs:\n          amountPaid:\n            sum: amountPaid\n          priceWithTax:\n            sum: priceWithTax\n    withValues: {}\n\nGet document PDF token (append to https://api.jobtread.com/t/{{token}}):\n\npdfToken:\n  _: signQuery\n  $:\n    query:\n      pdf:\n        $:\n          id: \"DOCUMENT_ID\""
      },
      {
        "title": "8. Custom fields",
        "body": "Read a record's custom field values (limit 25 per request):\n\naccount:\n  $:\n    id: \"ACCOUNT_ID\"\n  customFieldValues:\n    $:\n      size: 25\n    nodes:\n      id: {}\n      value: {}\n      customField:\n        id: {}\n\nUpdate a custom field via customFieldValues map:\n\nupdateAccount:\n  $:\n    id: \"ACCOUNT_ID\"\n    customFieldValues:\n      \"CUSTOM_FIELD_ID\": \"New value\"\n  account:\n    id: {}"
      },
      {
        "title": "9. Webhooks",
        "body": "Use the JobTread UI to create a webhook (Webhooks page) and copy its ID.\nManage them via the API: list webhook(id: \"ID\") or deleteWebhook to cancel.\nExample create query:\n\ncreateWebhook:\n  $:\n    organizationId: \"ORG_ID\"\n    url: \"https://your-endpoint/hooks/jobtread\"\n    eventTypes:\n      - jobCreated\n      - documentUploaded\n  createdWebhook:\n    id: {}\n    url: {}"
      },
      {
        "title": "Using This Skill with OpenClaw",
        "body": "Use curl or your preferred HTTP client from OpenClaw's exec tool.\nBuild the JSON payload as shown (always include the grant key inside $).\nYou can also wrap the payload in shell variables or helper scripts for portability.\nSave reusable queries in the skill file or separate scripts so Claude or you can call them by name (\"run job summary\", \"create customer\", etc.).\nDocument each automation in the JobTread vault so you can copy/paste from future sessions without digging through logs."
      },
      {
        "title": "Automation Ideas",
        "body": "Nightly job summary: Query each open job, sum approved customer orders, and store results in Obsidian (or send via WhatsApp).\nWebhook monitor: Automatically spin up a webhook for file uploads and forward notifications to your Slack/WhatsApp via a small server.\nBatch account creation: Feed a CSV of customers/vendors and run createAccount for each with the same grant key.\nDocument check-ins: Query documents with status: pending and send you a summary each morning."
      },
      {
        "title": "Troubleshooting & Tips",
        "body": "Rate limits: Grant keys have a throughput cap. If you hit rate limits, add time.sleep between requests or batch fewer objects.\nMissing IDs: The API complains id field required when you forget to request id. Always include it when you plan to mutate the record later.\nGrant expiration: If a request returns invalid key, rotate the grant and update ~/.config/jobtread/grant_key.\nWebhooks: Keep a log of webhook IDs so you can disable or reconfigure them later.\nSigned tokens: Use signQuery when you need temporary access to document PDFs without storing raw document IDs."
      }
    ],
    "body": "Skill: JobTread via Pave Query API\nSummary\n\nThis 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.\n\nSetup & Credentials\nCreate a grant: Login to https://app.jobtread.com/grants and create a new grant for automation. Copy the one-time grantKey (it begins with grant_ and will only show once).\nStore the key locally: Use a secure file such as ~/.config/jobtread/grant_key. Example:\nmkdir -p ~/.config/jobtread\necho \"grant_xxx\" > ~/.config/jobtread/grant_key\nchmod 600 ~/.config/jobtread/grant_key\n\nKeep 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.\nOptional 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.\nAuthentication\nEvery POST to /pave must include the grant key under query.$.grantKey. Example payload:\n{\n  \"query\": {\n    \"$\": { \"grantKey\": \"grant_xxx\" },\n    \"currentGrant\": { \"id\": {}, \"user\": { \"name\": {} } }\n  }\n}\n\nYou can also set notify, timeZone, or viaUserId inside $ when you need to suppress notifications or scope results.\nFor signed queries (PDF tokens, pre-signed data), call pdfToken: { _: signQuery, $: { query: {...} } } and append the token to https://api.jobtread.com/t/.\nAPI Basics & Request Flow\nAll requests go to POST https://api.jobtread.com/pave with Content-Type: application/json.\nStructure:\n{\n  \"query\": {\n    \"$\": { \"grantKey\": \"grant_xxx\" },  \n    \"operation\": {\n      \"$\": { ...inputs... },\n      \"field\": { ...fields... }\n    }\n  }\n}\n\nFields you request (id, name, etc.) determine what JobTread returns. Always include id when you plan to reference the object later.\n_type in responses tells you the schema for that node.\nCommon Patterns & Examples\n1. Discover your organization ID\ncurrentGrant:\n  user:\n    memberships:\n      nodes:\n        organization:\n          id: {}\n          name: {}\n\n\nUse the returned organization.id in any following query.\n\n2. Create customers/vendors\nCustomer\ncreateAccount:\n  $:\n    name: \"Test Customer\"\n    type: customer\n    organizationId: \"ORG_ID\"\n  createdAccount:\n    id: {}\n    name: {}\n    type: {}\n\nVendor (same as above but type: vendor).\n3. Read or update accounts\nRead account by supplying id and requesting fields:\naccount:\n  $:\n    id: \"ACCOUNT_ID\"\n  id: {}\n  name: {}\n  isTaxable: {}\n\nUpdate and include customFieldValues if needed:\nupdateAccount:\n  $:\n    id: \"ACCOUNT_ID\"\n    isTaxable: false\n  account:\n    id: {}\n    isTaxable: {}\n\n4. Query accounts list with pagination, sorting, and filters\norganization:\n  $: {}\n  id: {}\n  accounts:\n    $:\n      size: 5\n      page: \"1\"\n      sortBy:\n        - field: type\n          order: desc\n      where:\n        and:\n          - - type\n            - =\n            - customer\n          - - name\n            - =\n            - \"Sebas Clients\"\n    nextPage: {}\n    nodes:\n      id: {}\n      name: {}\n      type: {}\n\n5. Use where with or, nested fields, or custom fields\nFind account by custom field name:\norganization:\n  $: {}\n  id: {}\n  contacts:\n    $:\n      with:\n        cf:\n          _: customFieldValues\n          $:\n            where:\n              - - customField\n                - name\n              - \"VIP\"\n            values:\n              $:\n                field: value\n      where:\n        - - cf\n          - values\n        - =\n        - \"Yes\"\n    nodes:\n      id: {}\n      name: {}\n\n6. Locations and nested filters\n\nCreate location and find others tied to the same account:\n\ncreateLocation:\n  $:\n    accountId: \"ACCOUNT_ID\"\n    name: Test Location\n    address: \"123 Main St\"\n  createdLocation:\n    id: {}\n    name: {}\n\norganization:\n  $: {}\n  id: {}\n  locations:\n    $:\n      where:\n        - - account\n          - name\n        - Test Name\n    nodes:\n      id: {}\n      name: {}\n      account:\n        id: {}\n        name: {}\n\n7. Documents, jobs, and aggregates\nGet a job's documents grouped by type/status and sums:\njob:\n  $:\n    id: \"JOB_ID\"\n  documents:\n    $:\n      where:\n        - - type\n          - in\n          - - customerInvoice\n            - customerOrder\n      group:\n        by:\n          - type\n          - status\n        aggs:\n          amountPaid:\n            sum: amountPaid\n          priceWithTax:\n            sum: priceWithTax\n    withValues: {}\n\nGet document PDF token (append to https://api.jobtread.com/t/{{token}}):\npdfToken:\n  _: signQuery\n  $:\n    query:\n      pdf:\n        $:\n          id: \"DOCUMENT_ID\"\n\n8. Custom fields\nRead a record's custom field values (limit 25 per request):\naccount:\n  $:\n    id: \"ACCOUNT_ID\"\n  customFieldValues:\n    $:\n      size: 25\n    nodes:\n      id: {}\n      value: {}\n      customField:\n        id: {}\n\nUpdate a custom field via customFieldValues map:\nupdateAccount:\n  $:\n    id: \"ACCOUNT_ID\"\n    customFieldValues:\n      \"CUSTOM_FIELD_ID\": \"New value\"\n  account:\n    id: {}\n\n9. Webhooks\nUse the JobTread UI to create a webhook (Webhooks page) and copy its ID.\nManage them via the API: list webhook(id: \"ID\") or deleteWebhook to cancel.\nExample create query:\ncreateWebhook:\n  $:\n    organizationId: \"ORG_ID\"\n    url: \"https://your-endpoint/hooks/jobtread\"\n    eventTypes:\n      - jobCreated\n      - documentUploaded\n  createdWebhook:\n    id: {}\n    url: {}\n\nUsing This Skill with OpenClaw\nUse curl or your preferred HTTP client from OpenClaw's exec tool.\nBuild the JSON payload as shown (always include the grant key inside $).\nYou can also wrap the payload in shell variables or helper scripts for portability.\nSave reusable queries in the skill file or separate scripts so Claude or you can call them by name (\"run job summary\", \"create customer\", etc.).\nDocument each automation in the JobTread vault so you can copy/paste from future sessions without digging through logs.\nAutomation Ideas\nNightly job summary: Query each open job, sum approved customer orders, and store results in Obsidian (or send via WhatsApp).\nWebhook monitor: Automatically spin up a webhook for file uploads and forward notifications to your Slack/WhatsApp via a small server.\nBatch account creation: Feed a CSV of customers/vendors and run createAccount for each with the same grant key.\nDocument check-ins: Query documents with status: pending and send you a summary each morning.\nTroubleshooting & Tips\nRate limits: Grant keys have a throughput cap. If you hit rate limits, add time.sleep between requests or batch fewer objects.\nMissing IDs: The API complains id field required when you forget to request id. Always include it when you plan to mutate the record later.\nGrant expiration: If a request returns invalid key, rotate the grant and update ~/.config/jobtread/grant_key.\nWebhooks: Keep a log of webhook IDs so you can disable or reconfigure them later.\nSigned tokens: Use signQuery when you need temporary access to document PDFs without storing raw document IDs."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/Brokenwatch24/jobtread-api",
    "publisherUrl": "https://clawhub.ai/Brokenwatch24/jobtread-api",
    "owner": "Brokenwatch24",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/jobtread-api",
    "downloadUrl": "https://openagent3.xyz/downloads/jobtread-api",
    "agentUrl": "https://openagent3.xyz/skills/jobtread-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/jobtread-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/jobtread-api/agent.md"
  }
}