HomeBrowseUpload
← Back to registry
// Skill profile

CompanyCam

name: companycam

by byungkyu · published 2026-03-22

邮件处理数据处理加密货币
Total installs
0
Stars
★ 0
Last updated
2026-03
// Install command
$ claw add gh:byungkyu/byungkyu-companycam
View on GitHub
// Full documentation

---

name: companycam

description: |

CompanyCam API integration with managed OAuth. Photo documentation platform for contractors.

Use this skill when users want to manage projects, photos, users, tags, groups, or documents in CompanyCam.

For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).

compatibility: Requires network access and valid Maton API key

metadata:

author: maton

version: "1.0"

clawdbot:

emoji: 🧠

homepage: "https://maton.ai"

requires:

env:

- MATON_API_KEY

---

# 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

1. Sign in or create an account at [maton.ai](https://maton.ai)

2. Go to [maton.ai/settings](https://maton.ai/settings)

3. 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.

API Reference

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)
  • Code Examples

    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

    | Operation | Limit |

    |-----------|-------|

    | GET requests | 240 per minute |

    | POST/PUT/DELETE | 100 per minute |

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

    Error Handling

    | Status | Meaning |

    |--------|---------|

    | 400 | Bad request or missing CompanyCam connection |

    | 401 | Invalid or missing Maton API key |

    | 404 | Resource not found |

    | 422 | Validation error (check error messages) |

    | 429 | Rate limited |

    | 4xx/5xx | Passthrough error from CompanyCam API |

    Troubleshooting: API Key Issues

    1. Check that the `MATON_API_KEY` environment variable is set:

    echo $MATON_API_KEY

    2. 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

    1. 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](https://docs.companycam.com)
  • [CompanyCam API Reference](https://docs.companycam.com/reference)
  • [CompanyCam Getting Started](https://docs.companycam.com/docs/getting-started)
  • [Maton Community](https://discord.com/invite/dBfFAcefs2)
  • [Maton Support](mailto:support@maton.ai)
  • // Comments
    Sign in with GitHub to leave a comment.
    // Related skills

    More tools from the same signal band