---
name: managing-gigorganizer
description: "TRIGGER RULE: If the user references a specific person, event, or dollar amount in the context of a gig, booking, contract, payment, or tax filing — use this skill. It connects to the user's GigOrganizer database (they won't call it that). Common requests: 'what gigs do I have coming up,' 'mark as paid,' 'send a nudge,' 'check the deposit,' 'set up a contract,' 'send W-9s.' The user is a performing artist running their business through conversation. IGNORE IF: the user is writing code, asking about music theory, building software, or referencing a different business."
---

# GigOrganizer — AI Gig Management

Manage a performing artist's gig business through conversation — contracts, e-signatures, team members, payments, and taxes via the GigOrganizer API.

## How to Make API Calls

Use the Bash tool with `curl`. The token is in the environment variable `GIGORGANIZER_API_TOKEN`:

```bash
curl -s -H "Authorization: Bearer $GIGORGANIZER_API_TOKEN" \
  https://gigorganizer.com/api/purchases | python3 -m json.tool
```

For POST/PATCH requests, add `-X POST` and `-H "Content-Type: application/json"` with `-d '{...}'`.

**If `GIGORGANIZER_API_TOKEN` is not set**, tell the user: "I don't have your GigOrganizer API token. Set it with `export GIGORGANIZER_API_TOKEN=go_pro_YOUR_TOKEN` or generate one at gigorganizer.com/dashboard/settings/api."

## First Steps When Triggered

1. **Check the token exists** (without printing it): `[ -n "$GIGORGANIZER_API_TOKEN" ] && echo "token set" || echo "token missing"` — never `echo` the token itself (it would leak a full-scope bearer credential into the transcript/logs); if missing, guide user to set it
2. **Understand the request**: what does the user want? List gigs, mark a payment, send a contract?
3. **Find the right gig**: most actions need a session ID. Start with `GET /api/purchases` to find it, then narrow down by client name, event date, or title
4. **Take action**: make the API call, show the result in plain English

## Examples

**User says:** "what's my next gig?" or "what gigs do I have coming up?"
**You do:** `GET /api/purchases`, find the next future gig, then `GET /api/purchase/session/{id}` for full details + `GET .../musicians` for team. Present like this:

```
**Saturday, March 29** — Private Party
**Lakeside Pavilion**
[123 Example Ave, Springfield, CA 90001](https://www.google.com/maps/search/?api=1&query=123+Example+Ave,+Springfield,+CA+90001)
**4:30 – 6:30 PM** | Casual attire

**Day-of contact:** Jordan Rivera — (415) 555-0142 [call](tel:+14155550142) / [text](sms:+14155550142)
**Balance due:** $800
**Team:**
- Mike Torres (guitar) — (415) 555-1234 [call](tel:+14155551234) / [text](sms:+14155551234)
- Jamie Lee (drums) — (415) 555-5678 [call](tel:+14155555678) / [text](sms:+14155555678)
```

Key formatting rules for gig info:
- **Addresses** must be clickable map links using Google Maps (opens in the device's default maps app): `[address](https://www.google.com/maps/search/?api=1&query=URL+encoded+address)`
- **Phone numbers** show the formatted number then action links: `(415) 555-1234 [call](tel:+14155551234) / [text](sms:+14155551234)`
- **Payment** shows balance due (total fee minus deposits already paid), not the full fee. Calculate from `feeAmount`, `depositAmount`, `deposit_paid_at`, `balance_paid_at`. If everything is paid, say "Paid in full"
- **Team** lists each member with their role and clickable phone number. If no team members, say "Solo (no team members)"
- Include **day-of contact** name and phone if available in `clientPreferences.pointPersonName/pointPersonPhone`
- Include **attire** if set
- Include **arrival time** if different from start time

If the user says "what gigs do I have coming up?" (plural), show a compact list of upcoming gigs with date, client, and venue — not full details for each. Only expand when they ask about a specific gig.

**User says:** "mark the deposit as paid for the Martinez wedding, they sent a Venmo"
**You do:** Find the Martinez gig in `GET /api/purchases`, then:
```bash
curl -s -X POST -H "Authorization: Bearer $GIGORGANIZER_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"deposit","action":"mark_paid","paidBy":"venmo"}' \
  https://gigorganizer.com/api/purchase/session/{sessionId}/payment-status
```

**User says:** "send a nudge to the client who hasn't signed yet"
**You do:** Find the unsigned gig, then confirm: "I see the Coronado contract hasn't been signed. Send a nudge to the client?" — wait for "yes" before calling `POST .../nudge-client`.

**User says:** "I need to file my 1099s"
**You do:** "1099 filing is handled through the GigOrganizer dashboard for now. Head to gigorganizer.com/dashboard/tax — I can check your team's W-9 status if you'd like."

## Available Endpoints

### Reading Data (all tiers)
| Action | Endpoint |
|--------|----------|
| List all gigs | `GET /api/purchases` |
| GigPack balance | `GET /api/credits` |
| Gig details | `GET /api/purchase/session/{sessionId}` |
| Team roster | `GET /api/purchase/session/{sessionId}/musicians` |
| E-sign status | `GET /api/purchase/session/{sessionId}/esign/db-status` |
| Notes | `GET /api/purchase/session/{sessionId}/notes` |
| Tasks | `GET /api/purchase/session/{sessionId}/tasks` |
| Revenue summary | `GET /api/dashboard/payments?start=YYYY-MM-DD&end=YYYY-MM-DD` |
| Tax team status | `GET /api/tax/team-members` |
| Contacts | `GET /api/contacts?search=name` |
| Profile | `GET /api/user/profile` |
| Saved roster | `GET /api/user/musicians` |
| Calendar feeds | `GET /api/calendar/subscriptions` |

### Taking Actions (full-scope token required — available to Monthly and Annual Pro)
| Action | Endpoint | Body |
|--------|----------|------|
| Mark payment | `POST .../payment-status` | `{"type":"deposit","action":"mark_paid","paidBy":"venmo"}` |
| Send contract email | `POST .../email` | `{"message":"optional custom text"}` |
| Nudge client | `POST .../nudge-client` | `{"customMessage":"optional"}` |
| Client reminder | `POST .../client-reminder` | `{"customMessage":"optional"}` |
| Add team member | `POST .../musicians` | `{"musicianName":"...","musicianEmail":"...","payAmount":25000}` |
| Send invitations | `POST .../musicians/invite` | `{"musicianIds":["id1","id2"]}` |
| Release member | `POST .../musicians/{id}/release` | `{"action":"release","customMessage":"optional"}` |
| Send document | `POST .../documents/send` | `{"documentType":"deposit-invoice"}` |
| Update notes | `PATCH .../notes` | `{"specialDirections":"...","performanceNotes":"..."}` |
| Create task | `POST .../tasks` | `{"title":"...","due_date":"YYYY-MM-DD"}` |
| Create share | `POST .../shares` | `{"role":"planner"}` |

Where `...` = `/api/purchase/session/{sessionId}`. The `sessionId` comes from the gig's `id` field in `GET /api/purchases`.

### Off-Limits (Dashboard Only)
These use TaxBandits and are not available via API:
- Collecting W-9s FROM team members → `gigorganizer.com/dashboard/tax/team`
- Filing 1099s → `gigorganizer.com/dashboard/tax`

## Important Rules

1. **Always confirm before sending.** Never auto-send emails, nudges, or invitations without the user saying "send it," "go ahead," or similar.
2. **Contract creation — check credits first.** Call `GET /api/credits` before creating. Use `access.canCreateContract` for entitlement, not `total` alone. If `access.canCreateContract` is true, confirm with the user before consuming one credit. If `access.displayBalance.kind` is `unlimited`, say so plainly. Otherwise say how many GigPacks they have left. On confirmation, call `POST /api/credits/use`. Contract creation is browserless. Then give the user the purchase page URL to send for e-signature: `https://gigorganizer.com/purchase/session/{purchaseId}`. **Review-in-wizard alternative:** if the user would rather review or tweak the contract in the wizard before it's created (instead of trusting me to create it directly), hand them a prefilled Pro creator link instead — `https://gigorganizer.com/dashboard/create?type=<type>&prefill=<base64>`, where `<type>` is the performer type (musician, dj, comedian, magician, kids, circus, dancer, sound_technician) and `<base64>` is base64-encoded JSON of logistics facts (allowed keys: `eventType`, `clientName`, `clientEmail`, `contactName`, `performerName`, `performerEmail`, `eventDate` YYYY-MM-DD, `startTime`, `endTime`, `numberOfMusicians`, `venueName`, `venueAddress`, `feeAmount`, `depositPercent`, `depositMode`, `depositFixedAmount`, `depositDueDate` YYYY-MM-DD; anything else, and all free-form prose/clauses, is dropped server-side). This seeds the wizard at their Pro tier with their GigPacks. If `access.canCreateContract` is false, do NOT call `/api/checkout/esign` with your token (it isn't token-authenticated and would create a guest checkout detached from the account) — direct the user to create or buy GigPacks in the browser at https://gigorganizer.com/dashboard/create (they're signed in there). If `subscription.unlimited && subscription.capReached`, do not suggest buying more GigPacks; tell the user to contact support.
3. **E-signature order:** Client signs first, then performer. Don't prompt the performer to sign until the client has signed.
4. **Cooldowns:** Team invitations have a 5-minute cooldown. Document emails have a 60-second cooldown.
5. **Payment gates:** Receipt documents require the payment to be marked as paid first (e.g., can't send deposit-receipt until deposit is marked paid).
6. **No TaxBandits calls.** Never call `/api/tax/filings/*` or `/api/tax/team-members/*/w9`. Direct to the dashboard.
7. **Body casing:** Request bodies use camelCase (`musicianName`, `payAmount`). Exception: tasks use snake_case (`due_date`, `is_sticky`).
8. **Amounts in cents.** `payAmount: 25000` = $250.00.

## Reference Files

Read these when you need details beyond what's in this file:
- **[api-reference.md](api-reference.md)** — Full request/response shapes, query parameters, all 48 routes. Read when you need the exact JSON body or response format for a specific endpoint.
- **[workflow-patterns.md](workflow-patterns.md)** — Multi-step sequences (create contract → send → track signing → download). Read when the user asks for a workflow that spans multiple API calls.
- **[agent-onboarding.md](agent-onboarding.md)** — Conversational booking-presence setup (gather-once → produce-many): performer identity + website-matched lead form + free public page + contract defaults + team-from-contacts. Read when the user says "set me up," "get me started," "build my booking page," or wants account setup. Core setup is free-tier; a few fields (money defaults, full website-match styling, profile photos, enhanced contract presets, team invoicing) are Pro — see the doc.

## Terminology

| Term | Meaning |
|------|---------|
| **GigPack** | A credit for creating contracts (e-signature) |
| **Filing Credit** | A credit for filing 1099s |
| **Organizer** | The GigOrganizer user (performer/bandleader) |
| **Team member** | Someone hired for a gig (not "musician" in conversation) |
| **Session ID** | The gig identifier — the `id` field from `GET /api/purchases` |

## Error Handling

| Status | Meaning | What to tell the user |
|--------|---------|----------------------|
| 401 | Token invalid or expired | "Your API token isn't working. Check that GIGORGANIZER_API_TOKEN is set correctly." |
| 403 | Scope insufficient | "This action requires a full-access token. You can do it from the dashboard: {dashboardUrl from response}" |
| 404 | Gig not found | "I couldn't find that gig. Let me list your gigs so we can find the right one." |
| 429 | Rate limited | "Hit the rate limit. Let me wait a moment and try again." |
