Use Cursor to help build integrations with the COR API. This guide shows how to configure Cursor with project rules optimized for COR API development.Documentation Index
Fetch the complete documentation index at: https://developers.projectcor.com/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
- Cursor editor installed
- COR API credentials (API Key and Client Secret)
Project rules
Create project rules that provide Cursor with context about COR APIs. In your project root:mkdir -p .cursor
.cursor/rules.md:
# COR API Development Rules
You are an AI assistant specialized in building integrations with the COR platform APIs.
## Platform Overview
COR is a project management platform for agencies and professional services. The platform provides three APIs:
| API | Base URL | Purpose |
|-----|----------|---------|
| Main API | `https://api.projectcor.com/v1` | Core platform operations |
| Resource Allocation | `https://planner.svc.v2.projectcor.com` | User capacity management |
| Integrations API | `https://integrations.projectcor.com` | External system synchronization |
## Authentication
All APIs use OAuth 2.0 with Bearer tokens. The same token works across all three APIs.
### Getting a Token (Client Credentials)
```bash
# 1. Encode credentials
echo -n "API_KEY:CLIENT_SECRET" | base64
# 2. Request token
curl -X POST 'https://api.projectcor.com/v1/oauth/token?grant_type=client_credentials' \
-H 'Authorization: Basic BASE64_CREDENTIALS'
```
### Using the Token
```
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
```
### Token Refresh
Tokens expire (check `expires_in`). Refresh before expiration:
```bash
curl -X POST 'https://api.projectcor.com/v1/oauth/refreshtoken' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'refresh_token=REFRESH_TOKEN'
```
## Main API Entities
### Core Entities
| Entity | Endpoints | Description |
|--------|-----------|-------------|
| Clients | `/clients` | Customer accounts |
| Projects | `/projects` | Project management |
| Tasks | `/tasks` | Task tracking |
| Hours | `/hours` | Time entries |
| Users | `/users` | Team members |
| Brands | `/brands` | Client brands |
| Products | `/products` | Brand products |
### Entity Relationships
```
Company
└── Clients
└── Brands
└── Products
└── Projects
└── Tasks
└── Hours (time entries)
└── Project Costs
└── Project Estimates
└── Users (with roles and positions)
```
### User Roles
| role_id | Role |
|---------|------|
| 1 | C-Level |
| 2 | Director |
| 3 | Project Manager |
| 4 | Collaborator |
| 5 | Freelancer |
| 6 | Client |
### Task Status Values
| Status | Description |
|--------|-------------|
| `nueva` | New |
| `en_proceso` | In progress |
| `estancada` | Stalled |
| `finalizada` | Completed |
### Project Status Values
| Status | Description |
|--------|-------------|
| `in_process` | Active |
| `finished` | Completed |
| `suspended` | On hold |
## Data Conventions
### Pagination
List endpoints return paginated responses by default:
```json
{
"total": "45",
"perPage": 20,
"page": 1,
"lastPage": 3,
"data": [...]
}
```
Parameters:
- `page`: Page number (default: 1). Set to `false` to get all results
- `perPage`: Items per page (default: 20)
### Filters
Use URL-encoded JSON for filtering:
```bash
# Filter projects by client and status
filters={"client_id":25855,"status":"in_process","archived":2}
# URL encode it
curl '.../projects?filters=%7B%22client_id%22%3A25855%7D'
```
### Date Formats
- Request dates: `YYYY-MM-DD` (e.g., `2025-01-15`)
- Response dates: `YYYY-MM-DD HH:mm:ss` or ISO 8601
## Resource Allocation API
Manages user capacity on projects.
### Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/allocation/saveAllocation` | Create allocation |
| PUT | `/allocation/updateAllocation` | Update allocation |
| DELETE | `/allocation/removeAllocation` | Delete allocation |
| GET | `/allocation/getAllocations/{projectId}` | Get project allocations |
### Allocation Object
```json
{
"userId": 1111,
"companyId": 1111,
"email": "user@example.com",
"resource": {
"typeId": "Project",
"entityId": 1111
},
"from": "2024-06-01",
"to": "2024-10-31",
"assignedByUserId": 11111,
"allocatedHours": 20
}
```
### Validation Rules
- `allocatedHours` cannot be empty
- `from` date must be before `to` date
- Date range cannot exceed 12 months
- No overlapping allocations for same user/project
### Allocation Errors
| Error | Description |
|-------|-------------|
| `InvalidAllocationError` | Invalid data (empty hours, bad dates, >12 months) |
| `AllocationAlreadyExistInDatesRangeError` | Overlapping allocation exists |
| `UserNotFoundError` | User doesn't exist |
| `UserNotHaveWorkDaysError` | User has no work days configured |
| `ProjectNotFoundError` | Project doesn't exist |
| `AllocationNotFoundError` | Allocation to update/delete not found |
## Integrations API
Synchronizes external systems with COR using external ID mapping.
### Required Field
All requests MUST include `metadata.source`:
```json
{
"metadata": {
"source": "SALESFORCE"
},
"id": "external-id-123",
"name": "Entity Name"
}
```
### Supported Sources
`JIRA`, `SALESFORCE`, `ADVERTMIND`, `QUICKBOOKS`, `ZAPIER`, `OKTA`, `MICROSOFT_DYNAMICS`, `GITHUB`, `MICROSOFT_TEAMS`, `VBS`, `SAP`, `GLOBANT`
### Integration Entities
| Entity | Operations |
|--------|------------|
| Projects | CREATE, UPDATE, DELETE |
| Clients | CREATE, UPDATE, DELETE |
| Users | CREATE, UPDATE, DELETE, Assign Position |
| Working Time | CREATE, DELETE |
| Contracts | CREATE, UPDATE, DELETE, Attach/Detach Users |
| Workspaces | CREATE, UPDATE |
| Brands | CREATE, UPDATE, DELETE |
### External ID Flow
1. You provide external ID (from your system)
2. COR creates entity and stores mapping
3. Future operations reference external ID
```bash
# Create with external ID
POST /v2/integrations/projects
{"metadata":{"source":"SALESFORCE"},"id":"SF-OPP-123","name":"Project"}
# Update using external ID
PUT /v2/integrations/projects/SF-OPP-123
{"metadata":{"source":"SALESFORCE"},"name":"Updated Project"}
```
### Integration Error Codes
| Code | Description |
|------|-------------|
| `ZC001` | Generic Error |
| `ZC002` | Validation Error |
| `ZC003` | API Request Exception |
| `ZC004` | Query Exception |
| `ZC005` | External Request Exception |
## HTTP Status Codes
| Code | Description |
|------|-------------|
| `200` | Success |
| `201` | Created |
| `204` | Success (No Content) |
| `400` | Bad Request - check required fields |
| `401` | Unauthorized - refresh token |
| `403` | Forbidden - insufficient permissions |
| `404` | Not Found - verify resource exists |
| `422` | Unprocessable Entity - validation error |
| `429` | Too Many Requests - implement backoff |
| `500` | Server Error - retry with backoff |
## Best Practices
### Token Management
- Store tokens securely (environment variables)
- Implement automatic token refresh before expiration
- Never hardcode credentials in source code
### Error Handling
- Always check response status codes
- Parse error responses for specific error types
- Implement exponential backoff for retries
### Rate Limiting
- Implement delays between bulk operations
- Use pagination instead of fetching all at once
- Cache responses when appropriate
### Data Integrity
- Validate required fields before sending requests
- Use transactions for related operations when possible
- Log all API interactions for debugging
## Code Examples
### List Projects with Filters
```python
import requests
import json
headers = {'Authorization': f'Bearer {token}'}
filters = json.dumps({'status': 'in_process', 'archived': 2})
response = requests.get(
'https://api.projectcor.com/v1/projects',
params={'page': 1, 'perPage': 50, 'filters': filters},
headers=headers
)
data = response.json()
for project in data['data']:
print(f"{project['id']}: {project['name']}")
```
### Create Integration Project
```python
response = requests.post(
'https://integrations.projectcor.com/v2/integrations/projects',
headers={**headers, 'Content-Type': 'application/json'},
json={
'metadata': {'source': 'SALESFORCE'},
'id': 'SF-OPP-12345',
'name': 'New Project',
'client_id': 'SF-ACC-67890',
'start': '2025-01-15',
'end': '2025-03-31'
}
)
```
### Create Resource Allocation
```python
response = requests.post(
'https://planner.svc.v2.projectcor.com/allocation/saveAllocation',
headers={**headers, 'Content-Type': 'application/json'},
json={
'userId': 1111,
'companyId': 1111,
'resource': {'typeId': 'Project', 'entityId': 5001},
'from': '2025-01-01',
'to': '2025-03-31',
'assignedByUserId': 1111,
'allocatedHours': 40
}
)
```

