# Send CompanyCam to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- 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.
## Suggested prompts
### New install

```text
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.
```
### Upgrade existing

```text
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.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "companycam",
    "name": "CompanyCam",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/byungkyu/companycam",
    "canonicalUrl": "https://clawhub.ai/byungkyu/companycam",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/companycam",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=companycam",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "SKILL.md",
      "LICENSE.txt"
    ],
    "downloadMode": "redirect",
    "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/companycam"
    },
    "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."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/companycam",
    "downloadUrl": "https://openagent3.xyz/downloads/companycam",
    "agentUrl": "https://openagent3.xyz/skills/companycam/agent",
    "manifestUrl": "https://openagent3.xyz/skills/companycam/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/companycam/agent.md"
  }
}
```
## Documentation

### CompanyCam

Access the CompanyCam API with managed OAuth authentication. Manage projects, photos, users, tags, groups, documents, and webhooks for contractor photo documentation.

### Quick Start

# List projects
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/companycam/v2/projects')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

### Base URL

https://gateway.maton.ai/companycam/v2/{resource}

Replace {resource} with the actual CompanyCam API endpoint path. The gateway proxies requests to api.companycam.com/v2 and automatically injects your OAuth token.

### Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

### Getting Your API Key

Sign in or create an account at maton.ai
Go to maton.ai/settings
Copy your API key

### Connection Management

Manage your CompanyCam OAuth connections at https://ctrl.maton.ai.

### List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=companycam&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

### Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'companycam'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

### Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "d274cf68-9e76-464c-92e3-ff274c44526e",
    "status": "ACTIVE",
    "creation_time": "2026-02-12T01:56:32.259046Z",
    "last_updated_time": "2026-02-12T01:57:38.944271Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "companycam",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

### Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

### Specifying Connection

If you have multiple CompanyCam connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/companycam/v2/projects')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'd274cf68-9e76-464c-92e3-ff274c44526e')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If omitted, the gateway uses the default (oldest) active connection.

### Company

Get Company

GET /companycam/v2/company

Returns the current company information.

### Users

Get Current User

GET /companycam/v2/users/current

List Users

GET /companycam/v2/users

Query parameters:

page - Page number
per_page - Results per page (default: 25)
status - Filter by status (active, inactive)

Create User

POST /companycam/v2/users
Content-Type: application/json

{
  "first_name": "John",
  "last_name": "Doe",
  "email_address": "john@example.com",
  "user_role": "standard"
}

User roles: admin, standard, limited

Get User

GET /companycam/v2/users/{id}

Update User

PUT /companycam/v2/users/{id}
Content-Type: application/json

{
  "first_name": "John",
  "last_name": "Smith"
}

Delete User

DELETE /companycam/v2/users/{id}

### Projects

List Projects

GET /companycam/v2/projects

Query parameters:

page - Page number
per_page - Results per page (default: 25)
query - Search query
status - Filter by status
modified_since - Unix timestamp for filtering

Create Project

POST /companycam/v2/projects
Content-Type: application/json

{
  "name": "New Construction Project",
  "address": {
    "street_address_1": "123 Main St",
    "city": "Los Angeles",
    "state": "CA",
    "postal_code": "90210",
    "country": "US"
  }
}

Get Project

GET /companycam/v2/projects/{id}

Update Project

PUT /companycam/v2/projects/{id}
Content-Type: application/json

{
  "name": "Updated Project Name"
}

Delete Project

DELETE /companycam/v2/projects/{id}

Archive Project

PATCH /companycam/v2/projects/{id}/archive

Restore Project

PUT /companycam/v2/projects/{id}/restore

### Project Photos

List Project Photos

GET /companycam/v2/projects/{project_id}/photos

Query parameters:

page - Page number
per_page - Results per page
start_date - Filter by start date (Unix timestamp)
end_date - Filter by end date (Unix timestamp)
user_ids - Filter by user IDs
group_ids - Filter by group IDs
tag_ids - Filter by tag IDs

Add Photo to Project

POST /companycam/v2/projects/{project_id}/photos
Content-Type: application/json

{
  "uri": "https://example.com/photo.jpg",
  "captured_at": 1609459200,
  "coordinates": {
    "lat": 34.0522,
    "lon": -118.2437
  },
  "tags": ["exterior", "front"]
}

### Project Comments

List Project Comments

GET /companycam/v2/projects/{project_id}/comments

Add Project Comment

POST /companycam/v2/projects/{project_id}/comments
Content-Type: application/json

{
  "comment": {
    "content": "Work completed successfully"
  }
}

### Project Labels

List Project Labels

GET /companycam/v2/projects/{project_id}/labels

Add Labels to Project

POST /companycam/v2/projects/{project_id}/labels
Content-Type: application/json

{
  "labels": ["priority", "urgent"]
}

Delete Project Label

DELETE /companycam/v2/projects/{project_id}/labels/{label_id}

### Project Documents

List Project Documents

GET /companycam/v2/projects/{project_id}/documents

Upload Document

POST /companycam/v2/projects/{project_id}/documents
Content-Type: application/json

{
  "uri": "https://example.com/document.pdf",
  "name": "Contract.pdf"
}

### Project Checklists

List Project Checklists

GET /companycam/v2/projects/{project_id}/checklists

Create Checklist from Template

POST /companycam/v2/projects/{project_id}/checklists
Content-Type: application/json

{
  "checklist_template_id": "template_id"
}

Get Project Checklist

GET /companycam/v2/projects/{project_id}/checklists/{checklist_id}

### Project Users

List Assigned Users

GET /companycam/v2/projects/{project_id}/assigned_users

Assign User to Project

PUT /companycam/v2/projects/{project_id}/assigned_users/{user_id}

### Project Collaborators

List Collaborators

GET /companycam/v2/projects/{project_id}/collaborators

### Photos

List All Photos

GET /companycam/v2/photos

Query parameters:

page - Page number
per_page - Results per page

Get Photo

GET /companycam/v2/photos/{id}

Update Photo

PUT /companycam/v2/photos/{id}
Content-Type: application/json

{
  "photo": {
    "captured_at": 1609459200
  }
}

Delete Photo

DELETE /companycam/v2/photos/{id}

List Photo Tags

GET /companycam/v2/photos/{id}/tags

Add Tags to Photo

POST /companycam/v2/photos/{id}/tags
Content-Type: application/json

{
  "tags": ["exterior", "completed"]
}

List Photo Comments

GET /companycam/v2/photos/{id}/comments

Add Photo Comment

POST /companycam/v2/photos/{id}/comments
Content-Type: application/json

{
  "comment": {
    "content": "Great progress!"
  }
}

### Tags

List Tags

GET /companycam/v2/tags

Create Tag

POST /companycam/v2/tags
Content-Type: application/json

{
  "display_value": "Exterior",
  "color": "#FF5733"
}

Get Tag

GET /companycam/v2/tags/{id}

Update Tag

PUT /companycam/v2/tags/{id}
Content-Type: application/json

{
  "display_value": "Interior",
  "color": "#3498DB"
}

Delete Tag

DELETE /companycam/v2/tags/{id}

### Groups

List Groups

GET /companycam/v2/groups

Create Group

POST /companycam/v2/groups
Content-Type: application/json

{
  "name": "Roofing Team"
}

Get Group

GET /companycam/v2/groups/{id}

Update Group

PUT /companycam/v2/groups/{id}
Content-Type: application/json

{
  "name": "Updated Team Name"
}

Delete Group

DELETE /companycam/v2/groups/{id}

### Checklists

List All Checklists

GET /companycam/v2/checklists

Query parameters:

page - Page number
per_page - Results per page
completed - Filter by completion status (true/false)

### Webhooks

List Webhooks

GET /companycam/v2/webhooks

Create Webhook

POST /companycam/v2/webhooks
Content-Type: application/json

{
  "url": "https://example.com/webhook",
  "scopes": ["project.created", "photo.created"]
}

Available scopes:

project.created
project.updated
project.deleted
photo.created
photo.updated
photo.deleted
document.created
label.created
label.deleted

Get Webhook

GET /companycam/v2/webhooks/{id}

Update Webhook

PUT /companycam/v2/webhooks/{id}
Content-Type: application/json

{
  "url": "https://example.com/new-webhook",
  "enabled": true
}

Delete Webhook

DELETE /companycam/v2/webhooks/{id}

### Pagination

CompanyCam uses page-based pagination:

GET /companycam/v2/projects?page=2&per_page=25

Query parameters:

page - Page number (default: 1)
per_page - Results per page (default: 25)

### JavaScript - List Projects

const response = await fetch(
  'https://gateway.maton.ai/companycam/v2/projects?per_page=10',
  {
    headers: {
      'Authorization': \`Bearer ${process.env.MATON_API_KEY}\`
    }
  }
);
const projects = await response.json();
console.log(projects);

### Python - List Projects

import os
import requests

response = requests.get(
    'https://gateway.maton.ai/companycam/v2/projects',
    headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
    params={'per_page': 10}
)
projects = response.json()
for project in projects:
    print(f"{project['name']}: {project['id']}")

### Python - Create Project with Photo

import os
import requests

headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
base_url = 'https://gateway.maton.ai/companycam/v2'

# Create project
project_response = requests.post(
    f'{base_url}/projects',
    headers=headers,
    json={
        'name': 'Kitchen Renovation',
        'address': {
            'street_address_1': '456 Oak Ave',
            'city': 'Denver',
            'state': 'CO',
            'postal_code': '80202',
            'country': 'US'
        }
    }
)
project = project_response.json()
print(f"Created project: {project['id']}")

# Add photo to project
photo_response = requests.post(
    f'{base_url}/projects/{project["id"]}/photos',
    headers=headers,
    json={
        'uri': 'https://example.com/kitchen-before.jpg',
        'tags': ['before', 'kitchen']
    }
)
photo = photo_response.json()
print(f"Added photo: {photo['id']}")

### Notes

Project IDs and other IDs are returned as strings
Timestamps are Unix timestamps (seconds since epoch)
Photos can be added via URL (uri parameter)
Comments must be wrapped in a comment object
Webhooks use scopes parameter (not events)
User roles: admin, standard, limited
IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
IMPORTANT: When piping curl output to jq, environment variables may not expand correctly. Use Python examples instead.

### Rate Limits

OperationLimitGET requests240 per minutePOST/PUT/DELETE100 per minute

When rate limited, the API returns a 429 status code. Implement exponential backoff for retries.

### Error Handling

StatusMeaning400Bad request or missing CompanyCam connection401Invalid or missing Maton API key404Resource not found422Validation error (check error messages)429Rate limited4xx/5xxPassthrough error from CompanyCam API

### Troubleshooting: API Key Issues

Check that the MATON_API_KEY environment variable is set:

echo $MATON_API_KEY

Verify the API key is valid by listing connections:

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

### Troubleshooting: Invalid App Name

Ensure your URL path starts with companycam. For example:

Correct: https://gateway.maton.ai/companycam/v2/projects
Incorrect: https://gateway.maton.ai/v2/projects

### Resources

CompanyCam API Documentation
CompanyCam API Reference
CompanyCam Getting Started
Maton Community
Maton Support
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: byungkyu
- Version: 1.0.0
## Source health
- Status: healthy
- Source download looks usable.
- Yavira can redirect you to the upstream package for this source.
- Health scope: source
- Reason: direct_download_ok
- Checked at: 2026-04-30T16:55:25.780Z
- Expires at: 2026-05-07T16:55:25.780Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/companycam)
- [Send to Agent page](https://openagent3.xyz/skills/companycam/agent)
- [JSON manifest](https://openagent3.xyz/skills/companycam/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/companycam/agent.md)
- [Download page](https://openagent3.xyz/downloads/companycam)