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:Copy
Ask AI
mkdir -p .cursor
.cursor/rules.md:
Copy
Ask AI
# 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
}
)
```

