PageSourceSearch

https://repsshield.com/assets/ApiDocsPage-CHUb02qa.js

js repsshield.com collected 2026-10-02 02:00:27 UTC 55,304 bytes, 207 lines download raw bytes

1import{z as S,aK as K,j as e,cy as U,aL as q,aN as M,B as h,i as y,aC as j,g as E,e as s,Z as R,ac as I,A as _,P as L,ah as H,x as G,b9 as Y,cz as B,aI as F,f as z,W as V}from"./index-DGo-vssZ.js";import{c as Z,r as f,L as k}from"./vendor-Qgthw7N1.js";import{K as m}from"./key-BMkuqIiD.js";/**
2 * @license lucide-react v0.453.0 - ISC
3 *
4 * This source code is licensed under the ISC license.
5 * See the LICENSE file in the root directory of this source tree.
6 */const C=S("CodeXml",[["path",{d:"m18 16 4-4-4-4",key:"1inbqp"}],["path",{d:"m6 8-4 4 4 4",key:"15zrgr"}],["path",{d:"m14.5 4-5 16",key:"e7oirm"}]]);/**
7 * @license lucide-react v0.453.0 - ISC
8 *
9 * This source code is licensed under the ISC license.
10 * See the LICENSE file in the root directory of this source tree.
11 */const W=S("FileUp",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M12 12v6",key:"3ahymv"}],["path",{d:"m15 15-3-3-3 3",key:"15xj92"}]]);/**
12 * @license lucide-react v0.453.0 - ISC
13 *
14 * This source code is licensed under the ISC license.
15 * See the LICENSE file in the root directory of this source tree.
16 */const O=S("Terminal",[["polyline",{points:"4 17 10 11 4 5",key:"akl6gq"}],["line",{x1:"12",x2:"20",y1:"19",y2:"19",key:"q2wloq"}]]),$={initial:{x:"100%",opacity:0}
16,animate:{x:0,opacity:1,transition:{type:"spring",stiffness:300,damping:30}},exit:{x:"-30%",opacity:0,transition:{type:"spring",stiffness:300,damping:30}}};function J({children:i,title:l,showBack:x=!1,backPath:p,onBack:N,headerRight:v,headerVariant:w="large",hideHeader:P=!1,contentClassName:A,disableAnimation:o=!1}){const b=o?Z.Fragment:K.div,u=o?{}:{initial:"initial",animate:"animate",exit:"exit",variants:$};return e.jsxs("div",{className:"flex flex-col min-h-screen md:block",children:[!P&&l&&e.jsx(U,{title:l,showBack:x,backPath:p,onBack:N,rightContent:v,variant:w}),e.jsx(b,{...u,children:e.jsx("main",{className:q("flex-1 overflow-y-auto overflow-x-hidden","scrollbar-hide","",A),children:i})})]})}function Q({text:i}){const[l,x]=f.useState(!1);return e.jsx("button",{className:"absolute top-3 right-3 p-1.5 rounded bg-white/10 hover:bg-white/20 transition-colors text-gray-300 hover:text-white",onClick:async()=>{await navigator.clipboard.writeText(i),x(!0),setTimeout(()=>x(!1),2e3)},title:"Copy",children:l?e.jsx(z,{className:"h-4 w-4 text-green-400"}):e.jsx(V,{className:"h-4 w-4"})})}function d({code:i,language:l="bash"}){return e.jsxs("div",{className:"relative",children:[e.jsx("pre",{className:"bg-gray-950 text-gray-100 rounded-lg p-4 overflow-x-auto text-sm leading-relaxed font-mono",children:e.jsx("code",{children:i})}),e.jsx(Q,{text:i})]})}function c({method:i}){const l={GET:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",POST:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",DELETE:"bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",PATCH:"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200"};return e.jsx("span",{className:`font-mono text-xs font-bold px-2 py-0.5 rounded ${l[i]}`,children:i})}function a({name:i,type:l,required:x,description:p}){return e.jsxs("tr",{className:"border-b border-gray-100 dark:border-gray-800 last:border-0",children:[e.jsxs("td",{className:"py-3 pr-4 align-top",children:[e.jsx("code",{className:"text-sm font-mono text-green-700 dark:text-green-400",children:i}),x&&e.jsx("span",{className:"ml-1.5 text-[10px] font-semibold text-red-500 uppercase tracking-wide",children:"req"})]}),e.jsx("td",{className:"py-3 pr-4 align-top",children:e.jsx("code",{className:"text-xs font-mono text-gray-500 dark:text-gray-400",children:l})}),e.jsx("td",{className:"py-3 text-sm text-gray-600 dark:text-gray-300",children:p})]})}function se(){f.useEffect(()=>{document.title="API Documentation — REPSShield"},[]);const i=`curl -X POST https://repsshield.com/api/v1/time-entries \\
17  -H "Authorization: Bearer reps_YOUR_KEY_HERE" \\
18  -H "Content-Type: application/json" \\
19  -d '{
20    "date": "2026-03-06",
21    "hours": 1.5,
22    "activityType": "Property Management",
23    "description": "Reviewed lease renewal for Unit 3B"
24  }'`,l=`const REPS_API_KEY = process.env.REPS_API_KEY;
25
26async function logHours({ date, hours, activityType, description }) {
27  const res = await fetch('https://repsshield.com/api/v1/time-entries', {
28    method: 'POST',
29    headers: {
30      'Authorization': \`Bearer \${REPS_API_KEY}\`,
31      'Content-Type': 'application/json',
32    },
33    body: JSON.stringify({ date, hours, activityType, description }),
34  });
35
36  if (!res.ok) {
37    const { error } = await res.json();
38    // All errors use { error: { code, message, suggestion } }
39    throw new Error(\`[\${error.code}] \${error.message}\`);
40  }
41
42  return res.json();
43}
44
45// Log 1.5 hours of property management work today
46await logHours({
47  date: new Date().toISOString().split('T')[0],
48  hours: 1.5,
49  activityType: 'Property Management',
50  description: 'Reviewed lease renewal for Unit 3B',
51});`,x=`import os, requests
52from datetime import date
53
54REPS_API_KEY = os.environ["REPS_API_KEY"]
55
56def log_hours(*, work_date: date, hours: float, activity_type: str, description: str = ""):
57    response = requests.post(
58        "https://repsshield.com/api/v1/time-entries",
59        headers={
60            "Authorization": f"Bearer {REPS_API_KEY}",
61            "Content-Type": "application/json",
62        },
63        json={
64            "date": work_date.isoformat(),
65            "hours": hours,
66            "activityType": activity_type,
67            "description": description,
68        },
69    )
70    response.raise_for_status()
71    return response.json()
72
73log_hours(
74    work_date=date.today(),
75    hours=1.25,
76    activity_type="Administrative",
77    description="Updated rent roll spreadsheet",
78)`,p=`// Tool 1 — Discover properties (run first to get propertyId values)
79{
80  "name": "list_reps_properties",
81  "description": "List the user's real estate properties from REPSShield. Call this to discover propertyId values before logging hours.",
82  "parameters": { "type": "object", "properties": {} }
83}
84
85// Tool 2 — Log work hours
86{
87  "name": "log_real_estate_hours",
88  "description": "Log work hours in REPSShield for IRS REPS compliance. Call this when the user completes real estate work.",
89  "parameters": {
90    "type": "object",
91    "properties": {
92      "date":         { "type": "string",  "description": "Date the work was done (YYYY-MM-DD)" },
93      "hours":        { "type": "number",  "description": "Hours worked — e.g. 1.5 = 1h 30m" },
94      "activityType": { "type": "string",  "description": "Real estate activity category" },
95      "description":  { "type": "string",  "description": "Short description of the work done" },
96      "propertyId":   { "type": "number",  "description": "ID from list_reps_properties" },
97      "evidence":     { "type": "object",  "description": "Optional — { base64, filename, mimeType } or { url, filename }" }
98    },
99    "required": ["date", "hours", "activityType"]
100  }
101}
102
103// Tool 3 — Query logged entries (for deduplication / audit)
104{
105  "name": "list_reps_entries",
106  "description": "List existing time entries from REPSShield. Use this to check for duplicates or review what has already been logged.",
107  "parameters": {
108    "type": "object",
109    "properties": {
110      "startDate":      { "type": "string" },
111      "endDate":        { "type": "string" },
112      "propertyId":     { "type": "number" },
113      "activityType":   { "type": "string" },
114      "approvalStatus": { "type": "string", "enum": ["pending", "approved"] }
115    }
116  }
117}
118
119// Tool 4 — Update an existing entry
120{
121  "name": "update_reps_entry",
122  "description": "Update an existing REPSShield time entry. Use to correct mistakes, assign a property, or attach evidence.",
123  "parameters": {
124    "type": "object",
125    "properties": {
126      "id":           { "type": "number", "description": "Entry ID from list_reps_entries" },
127      "propertyId":   { "type": "number" },
128      "description":  { "type": "string" },
129      "hours":        { "type": "number" },
130      "activityType": { "type": "string" },
131      "evidence":     { "type": "object" }
132    },
133    "required": ["id"]
134  }
135}`,N=`{
136  "id": 4821,
137  "userId": "user_abc123",
138  "date": "2026-03-06T00:00:00.000Z",
139  "hours": "1.50",
140  "activityType": "Property Management",
141  "description": "Reviewed lease renewal for Unit 3B",
142  "source": "manual",
143  "approvalStatus": "approved",
144  "createdAt": "2026-03-06T10:32:00.000Z"
145}`,v=`[
146  {
147    "id": 12,
148    "nickname": "Beachside Condo",
149    "address": "123 Ocean Dr",
150    "city": "Miami",
151    "state": "FL",
152    "zipCode": "33101",
153    "propertyType": "Short-term Rental",
154    "includeInProfitTracking": true,
155    "createdAt": "2025-01-15T00:00:00.000Z"
156  }
157]`,w=`{
158  "entries": [ { "id": 4821, "hours": "1.50", "activityType": "Property Management", ... } ],
159  "total": 47,
160  "limit": 100,
161  "offset": 0
162}`,P=`// 401 — Missing or invalid API key
163{
164  "error": {
165    "code": "UNAUTHORIZED",
166    "message": "Invalid or expired API key",
167    "suggestion": "Check that your key starts with 'reps_' and has not been revoked."
168  }
169}
170
171// 403 — Correct key, insufficient scope
172{
173  "error": {
174    "code": "FORBIDDEN",
175    "message": "Missing required scope: time_entries:write",
176    "suggestion": "Rotate your key and add the 'time_entries:write' scope in Settings → API Keys."
177  }
178}
179
180// 400 — Validation failure
181{
182  "error": {
183    "code": "VALIDATION_ERROR",
184    "message": "Validation failed",
185    "field": "hours",
186    "suggestion": "hours must be between 0.001 and 24"
187  }
188}`,A=`// Agents can self-provision keys without a browser session.
189// Requires an active user session cookie (logged-in user delegates to an agent).
190const res = await fetch('https://repsshield.com/api/v1/auth/api-keys', {
191  method: 'POST',
192  headers: {
193    'Authorization': \`Bearer \${REPS_API_KEY}\`,   // existing key with any scope
194    'Content-Type': 'application/json',
195  },
196  body: JSON.stringify({
197    name: 'my-agent-v2',
198    scopes: ['time_entries:read', 'time_entries:write'],
199    expiresAt: '2027-01-01T00:00:00Z',  // optional
200  }),
201});
202const { key } = await res.json();
203// key.plainKey — store this securely; it is shown only once`,[o,b]=f.useState("curl"),u={curl:i,node:l,python:x,ai:p},[g,D]=f.useState("post");return M()?e.jsxs(J,{title:"API Documentation",showBack:!0,onBack:()=>window.history.back(),headerVariant:"centered",contentClassName:"bg-gray-50 dark:bg-gray-900",children:[e.jsxs("div",{className:"bg-gradient-to-b from-gray-950 to-gray-900 text-white px-5 py-8",children:[e.jsxs("div",{className:"flex items-center gap-1.5 text-green-400 text-xs font-semibold uppercase tracking-wider mb-3",children:[e.jsx(C,{className:"h-3.5 w-3.5"}),"Developer API"]}),e.jsx("h1",{className:"text-2xl text-white font-bold leading-tight mb-3",children:"Log hours from any tool, automatically."}),e.jsx("p",{className:"text-sm text-gray-300 leading-relaxed mb-5",children:"The REPSShield API lets your AI agents, scripts, and automations create time entries on your behalf."}),e.jsx(k,{href:"/settings",children:e.jsxs(h,{className:"w-full bg-green-600 hover:bg-green-700 text-white gap-2 h-11",children:[e.jsx(m,{className:"h-4 w-4"}),"Generate an API key"]})})]}),e.jsxs("div",{className:"px-4 py-6 space-y-8",children:[e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"How it works"}),e.jsx("div",{className:"space-y-3",children:[{step:"1",icon:m,title:"Generate a key",desc:"Settings → API Keys — create a named key for each tool."},{step:"2",icon:O,title:"Discover & log",desc:"Fetch your property IDs from GET /api/v1/properties, then POST entries, list them, and update as needed."},{step:"3",icon:y,title:"Hours are logged",desc:"Entries appear in your Activity Ledger instantly, approved and ready for tax reporting."}].map(({step:t,icon:r,title:n,desc:T})=>e.jsxs("div",{className:"flex gap-3 p-4 rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx("div",{className:"w-7 h-7 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center text-green-700 dark:text-green-400 font-bold text-xs shrink-0",children:t}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold text-gray-900 dark:text-white text-sm",children:n}),e.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-0.5 leading-relaxed",children:T})]})]},t))})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"Authentication"}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(d,{code:"Authorization: Bearer reps_YOUR_KEY_HERE"}),e.jsx("p",{className:"text-xs text-gray-400 text-center",children:"or"}),e.jsx(d,{code:"X-API-Key: reps_YOUR_KEY_HERE"})]}),e.jsxs("div",{className:"mt-3 flex items-start gap-2 p-3 rounded-lg bg-amber-50 dark:bg-amber-950 border border-amber-200 dark:border-amber-800",children:[e.jsx(j,{className:"h-3.5 w-3.5 mt-0.5 shrink-0 text-amber-600 dark:text-amber-400"}),e.jsxs("p",{className:"text-xs text-amber-800 dark:text-amber-200 leading-relaxed",children:["Store your key as an env variable (e.g."," ",e.jsx("code",{className:"font-mono bg-amber-100 dark:bg-amber-900 px-0.5 rounded",children:"REPS_API_KEY"}),"). Never commit to version control."]})]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"Scopes"}),e.jsxs("div",{className:"mb-3 flex items-start gap-2 p-3 rounded-lg bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800",children:[e.jsx(E,{className:"h-3.5 w-3.5 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400"}),e.jsxs("p",{className:"text-xs text-blue-800 dark:text-blue-200 leading-relaxed",children:[e.jsx("strong",{children:"Backward-compatible:"})," Keys with no scopes (",e.jsx("code",{className:"font-mono bg-blue-100 dark:bg-blue-900 px-0.5 rounded",children:"scopes: []"}),") are ",e.jsx("strong",{children:"unrestricted"})," and keep working unchanged."]})]}),e.jsx("div",{className:"space-y-2",children:[{scope:"time_entries:read",endpoints:"GET /api/v1/time-entries"},{scope:"time_entries:write",endpoints:"POST + PATCH /api/v1/time-entries"},{scope:"properties:read",endpoints:"GET /api/v1/properties"}].map(({scope:t,endpoints:r})=>e.jsxs("div",{className:"p-3 rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx("code",{className:"text-xs font-mono text-green-700 dark:text-green-400",children:t}),e.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-0.5",children:r})]},t))})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"Error responses"}),e.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400 mb-3",children:["All errors return ",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded",children:"{ error: { code, message, suggestion? } }"})," so they are easy to handle in code."]}),e.jsx("div",{className:"space-y-2",children:[{status:"401",desc:"Invalid or expired API key"},{status:"403",desc:"Key lacks the required scope"},{status:"400",desc:"Validation failure — check error.field"}].map(({status:t,desc:r})=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400",children:r})]},t))})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"Qu
203ick start"}),e.jsx("div",{className:"flex border-b border-gray-200 dark:border-gray-800 overflow-x-auto scrollbar-hide mb-3",children:["curl","node","python","ai"].map(t=>e.jsx("button",{onClick:()=>b(t),className:`px-3 py-2 text-xs font-medium whitespace-nowrap transition-colors border-b-2 -mb-px flex-shrink-0 ${o===t?"border-green-600 text-green-700 dark:text-green-400":"border-transparent text-gray-500"}`,children:t==="ai"?"AI Schema":t.charAt(0).toUpperCase()+t.slice(1)},t))}),e.jsx(d,{code:u[o]}),o==="ai"&&e.jsxs("p",{className:"mt-2 text-xs text-gray-500 dark:text-gray-400",children:["Register as a function/tool in your AI assistant, then forward calls to"," ",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded",children:"POST /api/v1/time-entries"}),"."]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"API Reference"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"rounded-xl border border-gray-200 dark:border-gray-800 overflow-hidden",children:[e.jsxs("div",{className:"p-4 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(c,{method:"POST"}),e.jsx("code",{className:"font-mono text-xs text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries"}),e.jsx(s,{variant:"outline",className:"text-xs ml-auto",children:"API key required"}),e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"time_entries:write"})]}),e.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400 mb-2",children:["Required: ",e.jsx("code",{className:"font-mono",children:"date"}),", ",e.jsx("code",{className:"font-mono",children:"hours"}),", ",e.jsx("code",{className:"font-mono",children:"activityType"}),". Optional: ",e.jsx("code",{className:"font-mono",children:"evidence"})," (base64 or URL)"]})]}),e.jsxs("div",{className:"p-4 bg-gray-50 dark:bg-gray-950 space-y-1.5 border-t border-gray-200 dark:border-gray-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"201"}),e.jsx("span",{className:"text-xs text-gray-500",children:"Entry created"})]}),[["400","Validation error"],["401","Invalid/expired key"],["403","Missing time_entries:write scope"],["500","Server error"]].map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400",children:r})]},t))]})]}),e.jsxs("div",{className:"rounded-xl border border-gray-200 dark:border-gray-800 overflow-hidden",children:[e.jsxs("div",{className:"p-4 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(c,{method:"GET"}),e.jsx("code",{className:"font-mono text-xs text-gray-800 dark:text-gray-200",children:"/api/v1/properties"}),e.jsx(s,{variant:"outline",className:"text-xs ml-auto",children:"API key required"}),e.jsx(s,{className:"bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 text-xs",children:"properties:read"})]}),e.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:"Returns your property list with IDs. Call this first so agents can map activities to properties."})]}),e.jsxs("div",{className:"p-4 bg-gray-50 dark:bg-gray-950 space-y-1.5 border-t border-gray-200 dark:border-gray-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200"}),e.jsx("span",{className:"text-xs text-gray-500",children:"Array of property objects"})]}),[["401","Invalid/expired key"],["403","Missing properties:read scope"]].map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400",children:r})]},t))]})]}),e.jsxs("div",{className:"rounded-xl border border-gray-200 dark:border-gray-800 overflow-hidden",children:[e.jsxs("div",{className:"p-4 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(c,{method:"GET"}),e.jsx("code",{className:"font-mono text-xs text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries"}),e.jsx(s,{variant:"outline",className:"text-xs ml-auto",children:"API key required"}),e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"time_entries:read"})]}),e.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:["List logged entries. Filters: ",e.jsx("code",{className:"font-mono",children:"startDate"}),", ",e.jsx("code",{className:"font-mono",children:"endDate"}),", ",e.jsx("code",{className:"font-mono",children:"propertyId"}),", ",e.jsx("code",{className:"font-mono",children:"activityType"}),", ",e.jsx("code",{className:"font-mono",children:"approvalStatus"}),", ",e.jsx("code",{className:"font-mono",children:"limit"}),", ",e.jsx("code",{className:"font-mono",children:"offset"})]})]}),e.jsxs("div",{className:"p-4 bg-gray-50 dark:bg-gray-950 space-y-1.5 border-t border-gray-200 dark:border-gray-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200"}),e.jsx("span",{className:"text-xs text-gray-500",children:"{ entries, total, limit, offset }"})]}),[["401","Invalid/expired key"],["403","Missing time_entries:read scope"]].map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400",children:r})]},t))]})]}),e.jsxs("div",{className:"rounded-xl border border-gray-200 dark:border-gray-800 overflow-hidden",children:[e.jsxs("div",{className:"p-4 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 flex-wrap",children:[e.jsx(c,{method:"PATCH"}),e.jsx("code",{className:"font-mono text-xs text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries/:id"}),e.jsx(s,{variant:"outline",className:"text-xs ml-auto",children:"API key required"}),e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"time_entries:write"})]}),e.jsxs("p",{className:"text-xs text-gray-500 dark:text-gray-400",children:["Update mutable fields: ",e.jsx("code",{className:"font-mono",children:"propertyId"}),", ",e.jsx("code",{className:"font-mono",children:"description"}),", ",e.jsx("code",{className:"font-mono",children:"hours"}),", ",e.jsx("code",{className:"font-mono",children:"activityType"}),", ",e.jsx("code",{className:"font-mono",children:"evidence"})]})]}),e.jsxs("div",{className:"p-4 bg-gray-50 dark:bg-gray-950 space-y-1.5 border-t border-gray-200 dark:border-gray-800",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200"}),e.jsx("span",{className:"text-xs text-gray-500",children:"Updated entry"})]}),[["400","Validation / property not found"],["401","Invalid/expired key"],["403","Missing time_entries:write scope"],["404","Entry not found"]].map(([t,r])=>e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-xs text-gray-500 dark:text-gray-400",children:r})]},t))]})]})]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-base font-bold text-gray-900 dark:text-white mb-3",children:"Security tips"}),e.jsx("div",{className:"space-y-3",children:[{icon:j,title:"Use env variables",desc:"Never put your key in source code or commit it to version control."},{icon:m,title:"One key per tool",desc:"Name each key after the tool so you can revoke selectively."},{icon:R,title:"Rotate regularly",desc:"Create a new key and revoke the old one periodically."},{icon:y,title:"Set expiration",desc:"Supply an expiresAt date so the key self-revokes automatically."}
203].map(({icon:t,title:r,desc:n})=>e.jsxs("div",{className:"flex gap-3 p-4 rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx("div",{className:"shrink-0 w-7 h-7 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center",children:e.jsx(t,{className:"h-3.5 w-3.5 text-green-700 dark:text-green-400"})}),e.jsxs("div",{children:[e.jsx("p",{className:"font-semibold text-gray-900 dark:text-white text-sm",children:r}),e.jsx("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-0.5 leading-relaxed",children:n})]})]},r))})]}),e.jsxs("section",{className:"rounded-2xl bg-gradient-to-br from-green-600 to-green-800 text-white p-6 text-center mb-6",children:[e.jsx(I,{className:"h-8 w-8 mx-auto mb-3 opacity-80"}),e.jsx("h2",{className:"text-lg font-bold mb-2",children:"Ready to automate your hours?"}),e.jsx("p",{className:"text-green-200 text-sm mb-4",children:"Generate an API key and have your first automated entry logged in minutes."}),e.jsx(k,{href:"/settings",children:e.jsxs(h,{className:"w-full bg-white text-green-700 hover:bg-green-50 gap-2 font-semibold",children:["Go to Settings",e.jsx(_,{className:"h-4 w-4"})]})})]})]})]}):e.jsxs(L,{hideEmailIntake:!0,children:[e.jsx("section",{className:"bg-gradient-to-b from-gray-950 to-gray-900 text-white py-16 sm:py-24",children:e.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6",children:[e.jsxs("div",{className:"flex items-center gap-2 text-green-400 text-sm font-medium mb-4",children:[e.jsx(C,{className:"h-4 w-4"}),"Developer API"]}),e.jsxs("h1",{className:"text-3xl text-white sm:text-5xl font-bold mb-4 leading-tight",children:["Log hours from any tool,",e.jsx("br",{className:"hidden sm:block"})," automatically."]}),e.jsx("p",{className:"text-lg text-gray-300 max-w-2xl mb-8",children:"The REPSShield API lets your AI agents, scripts, and automations create time entries on your behalf — so your IRS REPS hours are always up to date."}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(k,{href:"/settings",children:e.jsxs(h,{className:"bg-green-600 hover:bg-green-700 text-white gap-2",children:[e.jsx(m,{className:"h-4 w-4"}),"Generate an API key"]})}),e.jsx("a",{href:"#reference",children:e.jsxs(h,{variant:"outline",className:"border-white/20 text-black hover:bg-white/10 hover:text-white gap-2",children:["View reference",e.jsx(H,{className:"h-4 w-4"})]})})]})]})}),e.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-6 py-12 sm:py-16 space-y-20",children:[e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-8",children:"How it works"}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-6",children:[{icon:m,step:"1",title:"Generate a key",desc:"Go to Settings → API Keys and create a named key for each tool you connect."},{icon:O,step:"2",title:"Discover & log",desc:"Fetch your property IDs from GET /api/v1/properties, then POST entries, list them with GET, and refine with PATCH."},{icon:y,step:"3",title:"Hours are logged",desc:"Entries appear in your Activity Ledger instantly, approved and ready for tax reporting."}].map(({icon:t,step:r,title:n,desc:T})=>e.jsxs("div",{className:"relative p-6 rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx("div",{className:"w-9 h-9 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center mb-4 text-green-700 dark:text-green-400 font-bold text-sm",children:r}),e.jsx(t,{className:"h-5 w-5 text-gray-400 mb-2"}),e.jsx("h3",{className:"font-semibold text-gray-900 dark:text-white mb-1",children:n}),e.jsx("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:T})]},r))})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"Authentication"}),e.jsx("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:"Every request must include your API key using one of these headers:"}),e.jsxs("div",{className:"space-y-3",children:[e.jsx(d,{code:"Authorization: Bearer reps_YOUR_KEY_HERE"}),e.jsx("p",{className:"text-sm text-gray-500 text-center",children:"or"}
203),e.jsx(d,{code:"X-API-Key: reps_YOUR_KEY_HERE"})]}),e.jsxs("div",{className:"mt-6 flex items-start gap-3 p-4 rounded-lg bg-amber-50 dark:bg-amber-950 border border-amber-200 dark:border-amber-800 text-sm text-amber-800 dark:text-amber-200",children:[e.jsx(j,{className:"h-4 w-4 mt-0.5 shrink-0"}),e.jsxs("p",{children:["Store your API key in an environment variable (e.g. ",e.jsx("code",{className:"font-mono bg-amber-100 dark:bg-amber-900 px-1 rounded",children:"REPS_API_KEY"}),"). Never hard-code it in source code or commit it to version control."]})]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"Scopes"}),e.jsx("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:"Scopes restrict what an API key is allowed to do. You choose scopes when creating or rotating a key in Settings → API Keys."}),e.jsxs("div",{className:"mb-6 flex items-start gap-3 p-4 rounded-lg bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800 text-sm text-blue-800 dark:text-blue-200",children:[e.jsx(E,{className:"h-4 w-4 mt-0.5 shrink-0 text-blue-600 dark:text-blue-400"}),e.jsxs("p",{children:[e.jsx("strong",{children:"Backward-compatible:"})," Keys created before scopes were introduced have an empty scopes list (",e.jsx("code",{className:"font-mono bg-blue-100 dark:bg-blue-900 px-1 rounded",children:"scopes: []"}),"), which is treated as ",e.jsx("strong",{children:"unrestricted — full access to all endpoints"}),". Those keys keep working unchanged."]})]}),e.jsx("div",{className:"overflow-x-auto rounded-xl border border-gray-200 dark:border-gray-800",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{className:"bg-gray-50 dark:bg-gray-900",children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"px-4 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Scope"}),e.jsx("th",{className:"px-4 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Grants access to"})]})}),e.jsx("tbody",{className:"bg-white dark:bg-gray-950 divide-y divide-gray-100 dark:divide-gray-800",children:[{scope:"time_entries:read",endpoints:"GET /api/v1/time-entries"},{scope:"time_entries:write",endpoints:"POST /api/v1/time-entries, PATCH /api/v1/time-entries/:id"},{scope:"properties:read",endpoints:"GET /api/v1/properties"}].map(({scope:t,endpoints:r})=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-4 py-3",children:e.jsx("code",{className:"text-sm font-mono text-green-700 dark:text-green-400",children:t})}),e.jsx("td",{className:"px-4 py-3 text-sm text-gray-600 dark:text-gray-300",children:e.jsx("code",{className:"font-mono text-xs text-gray-500 dark:text-gray-400",children:r})})]},t))})]})}),e.jsxs("p",{className:"mt-4 text-sm text-gray-500 dark:text-gray-400",children:["A key with ",e.jsx("strong",{children:"no scopes selected"})," (empty array) is unrestricted and may call any endpoint. Use specific scopes to follow the principle of least privilege."]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"Error responses"}),e.jsx("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:"All API errors return a consistent JSON shape so they are easy to handle programmatically."}),e.jsx(d,{code:P,language:"json"}),e.jsx("div",{className:"mt-4 overflow-x-auto rounded-xl border border-gray-200 dark:border-gray-800",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{className:"bg-gray-50 dark:bg-gray-900",children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"px-4 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Field"}),e.jsx("th",{className:"px-4 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Always present"}),e.jsx("th",{className:"px-4 py-3 text-xs font-semibold text-gray-500 uppercase tracking-wider",children:"Description"})]})}),e.jsx("tbody",{className:"bg-white dark:bg-gray-950 divide-y divide-gray-100 dark:divide-gray-800",children:[{field:"error.code",always:"Yes",desc:"Machine-readable error identifier (e.g. UNAUTHORIZED, FORBIDDEN, VALIDATION_ERROR)"},{field:"error.message",always:"Yes",desc:"Human-readable description of what went wrong"},{field:"error.field",always:"No",desc:"The request field that caused a validation failure"},{field:"error.suggestion",always:"No",desc:"Actionable hint to resolve the error"}].map(({field:t,always:r,desc:n})=>e.jsxs("tr",{children:[e.jsx("td",{className:"px-4 py-3",children:e.jsx("code",{className:"text-sm font-mono text-green-700 dark:text-green-400",children:t})}),e.jsx("td",{className:"px-4 py-3 text-sm text-gray-500",children:r}),e.jsx("td",{className:"px-4 py-3 text-sm text-gray-600 dark:text-gray-300",children:n})]},t))})]})})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"Qu
203ick start"}),e.jsx("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:"Log your first hour in under a minute."}),e.jsx("div",{className:"flex gap-1 mb-3 border-b border-gray-200 dark:border-gray-800",children:["curl","node","python","ai"].map(t=>e.jsx("button",{onClick:()=>b(t),className:`px-4 py-2 text-sm font-medium transition-colors border-b-2 -mb-px ${o===t?"border-green-600 text-green-700 dark:text-green-400":"border-transparent text-gray-500 hover:text-gray-700 dark:hover:text-gray-200"}`,children:t==="ai"?"AI Agent / Tool Schema":t.charAt(0).toUpperCase()+t.slice(1)},t))}),e.jsx(d,{code:u[o],language:o==="node"?"typescript":o==="ai"?"json":o}),o==="ai"&&e.jsxs("p",{className:"mt-3 text-sm text-gray-500 dark:text-gray-400",children:["Register this as a function/tool in your AI assistant (OpenAI, Claude, Cursor, etc.). When the assistant calls it, forward the arguments to ",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded",children:"POST /api/v1/time-entries"}),"."]})]}),e.jsxs("section",{id:"reference",children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"API Reference"}),e.jsxs("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:["Base URL: ",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded text-sm",children:"https://repsshield.com"})]}),e.jsx("div",{className:"flex gap-1 mb-6 border-b border-gray-200 dark:border-gray-800 overflow-x-auto",children:[{key:"post",label:"POST /time-entries",icon:y},{key:"get-properties",label:"GET /properties",icon:G},{key:"get-entries",label:"GET /time-entries",icon:Y},{key:"patch",label:"PATCH /time-entries/:id",icon:B}].map(({key:t,label:r,icon:n})=>e.jsxs("button",{onClick:()=>D(t),className:`flex items-center gap-1.5 px-4 py-2 text-sm font-medium whitespace-nowrap transition-colors border-b-2 -mb-px ${g===t?"border-green-600 text-green-700 dark:text-green-400":"border-transparent text-gray-500 hover:text-gray-700 dark:hover:text-gray-200"}`,children:[e.jsx(n,{className:"h-3.5 w-3.5"}),r]},t))}),e.jsxs("div",{className:"rounded-xl border border-gray-200 dark:border-gray-800 overflow-hidden",children:[g==="post"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"p-6 border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx(c,{method:"POST"}),e.jsx("code",{className:"font-mono text-sm text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries"}),e.jsx(s,{variant:"outline",className:"ml-auto text-xs",children:"API key required"}),e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"time_entries:write"})]}),e.jsxs("p",{className:"text-sm text-gray-600 dark:text-gray-300 mb-6",children:["Create a new time entry on behalf of the key owner. The primary endpoint for external tools and AI agents logging hours. Optionally attach evidence at creation time via ",e.jsx("code",{className:"font-mono text-xs",children:"evidence"}),"."]}),e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3",children:"Request body (JSON)"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 dark:text-gray-400 pr-4",children:"Field"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 dark:text-gray-400 pr-4",children:"Type"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 dark:text-gray-400",children:"Description"})]})}),e.jsxs("tbody",{children:[e.jsx(a,{name:"date",type:"string",required:!0,description:'ISO 8601 date — e.g. "2026-03-06"'}),e.jsx(a,{name:"hours",type:"number",required:!0,description:"Decimal hours — min 0.001, max 24. E.g. 1.5 = 1h 30m"}),e.jsx(a,{name:"activityType",type:"string",required:!0,description:"Category of real estate work (see common values below)"}),e.jsx(a,{name:"description",type:"string",description:"Free-text description of the specific work done"}),e.jsx(a,{name:"propertyId",type:"number",description:"Property ID from GET /api/v1/properties"}),e.jsx(a,{name:"propertyType",type:"string",description:'"Long-term Rental" or "Short-term Rental"'}),e.jsx(a,{name:"isMaterialParticipation",type:"boolean",description:"Whether this counts toward material participation"}),e.jsx(a,{name:"isQualifiedNonMaterial",type:"boolean",description:"Whether this is qualified non-material participation"}),e.jsx(a,{name:"timeStarted",type:"string",description:'Exact start timestamp, e.g. "2026-03-06T09:00:00Z"'}),e.jsx(a,{name:"timeEnded",type:"string",description:'Exact end timestamp, e.g. "2026-03-06T10:30:00Z"'}),e.jsx(a,{name:"evidence",type:"object | object[]",description:"Attach evidence at creation. Single item or array. See evidence schema below."})]})]})}),e.jsxs("div",{className:"mt-6 p-4 rounded-lg bg-blue-50 dark:bg-blue-950 border border-blue-200 dark:border-blue-800",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[e.jsx(W,{className:"h-4 w-4 text-blue-600 dar
203k:text-blue-400"}),e.jsx("span",{className:"text-xs font-semibold text-blue-800 dark:text-blue-200 uppercase tracking-wider",children:"Evidence schema"})]}),e.jsx("p",{className:"text-xs text-blue-700 dark:text-blue-300 mb-3",children:"Supply one of two shapes (or an array of either):"}),e.jsx(d,{code:`// Base64-encoded file (recommended for agents)
204{ "base64": "<base64 string>", "filename": "receipt.pdf", "mimeType": "application/pdf" }
205
206// Remote HTTPS URL (must be public; HTTP and private IPs are rejected)
207{ "url": "https://example.com/receipt.pdf", "filename": "receipt.pdf" }`,language:"json"}),e.jsx("p",{className:"text-xs text-blue-600 dark:text-blue-400 mt-2",children:"Evidence is uploaded to cloud storage and AI-analysed automatically. Supported types: PDF, images (JPEG/PNG/WebP), plain text, Word docs."})]}),e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mt-6 mb-3",children:"Common activityType values"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:["Property Management","Tenant Communication","Maintenance & Repairs","Administrative","Financial Review","Lease Management","Property Marketing","Research & Analysis","Travel"].map(t=>e.jsx("code",{className:"text-xs font-mono bg-gray-100 dark:bg-gray-800 px-2 py-0.5 rounded text-gray-700 dark:text-gray-300",children:t},t))})]}),e.jsxs("div",{className:"p-6 bg-gray-50 dark:bg-gray-950",children:[e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-4",children:"Response"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"201 Created"}),e.jsx("span",{className:"text-sm text-gray-500",children:"Entry created — full time entry object returned"})]}),e.jsx(d,{code:N,language:"json"}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-3 pt-2 text-sm",children:[["400","Validation error — check the errors array"],["401","Missing, invalid, or expired API key"],["403","Key lacks the time_entries:write scope"],["500","Server error — try again or contact support"]].map(([t,r])=>e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-gray-500 dark:text-gray-400",children:r})]},t))})]})]})]}),g==="get-properties"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"p-6 border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx(c,{method:"GET"}),e.jsx("code",{className:"font-mono text-sm text-gray-800 dark:text-gray-200",children:"/api/v1/properties"}),e.jsx(s,{variant:"outline",className:"ml-auto text-xs",children:"API key required"}),e.jsx(s,{className:"bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200 text-xs",children:"properties:read"})]}),e.jsxs("p",{className:"text-sm text-gray-600 dark:text-gray-300 mb-6",children:["Return all properties belonging to the API key owner's workspace. Use this to discover ",e.jsx("code",{className:"font-mono text-xs",children:"propertyId"})," values before creating or updating time entries. This is the recommended first call for any automated workflow."]}),e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3",children:"No request body or query params"}),e.jsx("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:"Authentication via API key is sufficient — no filters are needed."})]}),e.jsxs("div",{className:"p-6 bg-gray-50 dark:bg-gray-950",children:[e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-4",children:"Response"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200 OK"}),e.jsx("span",{className:"text-sm text-gray-500",children:"Array of property objects"})]}
207),e.jsx(d,{code:v,language:"json"}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-3 pt-2 text-sm",children:[["200","Array of property objects"],["401","Missing or invalid API key"],["403","Key lacks the properties:read scope"]].map(([t,r])=>e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-gray-500 dark:text-gray-400",children:r})]},t))}),e.jsx("div",{className:"overflow-x-auto mt-4",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Field"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Type"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500",children:"Description"})]})}),e.jsxs("tbody",{children:[e.jsx(a,{name:"id",type:"number",description:"Use as propertyId in POST / PATCH"}),e.jsx(a,{name:"nickname",type:"string",description:"Human-readable label for the property"}),e.jsx(a,{name:"address",type:"string",description:"Street address"}),e.jsx(a,{name:"city",type:"string",description:"City"}),e.jsx(a,{name:"state",type:"string",description:"State abbreviation"}),e.jsx(a,{name:"zipCode",type:"string",description:"ZIP code"}),e.jsx(a,{name:"propertyType",type:"string",description:'"Long-term Rental" | "Short-term Rental"'}),e.jsx(a,{name:"includeInProfitTracking",type:"boolean",description:"Whether this property is tracked for profit"}),e.jsx(a,{name:"createdAt",type:"string",description:"ISO 8601 creation timestamp"})]})]})})]})]})]}),g==="get-entries"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"p-6 border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx(c,{method:"GET"}),e.jsx("code",{className:"font-mono text-sm text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries"}),e.jsx(s,{variant:"outline",className:"ml-auto text-xs",children:"API key required"}),e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"time_entries:read"})]}),e.jsx("p",{className:"text-sm text-gray-600 dark:text-gray-300 mb-6",children:"List existing time entries with optional filters. Use this for reconciliation, deduplication, gap analysis, and audit preparation."}),e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3",children:"Query parameters (all optional)"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Param"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Type"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500",children:"Description"})]})}),e.jsxs("tbody",{children:[e.jsx(a,{name:"startDate",type:"string",description:"ISO 8601 start date (inclusive), e.g. 2026-01-01"}),e.jsx(a,{name:"endDate",type:"string",description:"ISO 8601 end date (inclusive), e.g. 2026-12-31"}),e.jsx(a,{name:"propertyId",type:"number",description:"Filter to a specific property"}),e.jsx(a,{name:"activityType",type:"string",description:"Filter by activity category"}),e.jsx(a,{name:"approvalStatus",type:"string",description:'"pending" or "approved"'}),e.jsx(a,{name:"limit",type:"number",description:"Max results to return (1–500, default 100)"}),e.jsx(a,{name:"offset",type:"number",description:"Pagination offset (default 0)"})]})]})})]}),e.jsxs("div",{className:"p-6 bg-gray-50 dark:bg-gray-950",children:[e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-4",children:"Response"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200 OK"}),e.jsx("span",{className:"text-sm text-gray-500",children:"Paginated entries list"})]}
207),e.jsx(d,{code:w,language:"json"}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-3 pt-2 text-sm",children:[["400","Invalid query params"],["401","Missing or invalid API key"],["403","Key lacks the time_entries:read scope"],["500","Server error"]].map(([t,r])=>e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-gray-500 dark:text-gray-400",children:r})]},t))})]})]})]}),g==="patch"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"p-6 border-b border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsxs("div",{className:"flex items-center gap-3 mb-4",children:[e.jsx(c,{method:"PATCH"}),e.jsx("code",{className:"font-mono text-sm text-gray-800 dark:text-gray-200",children:"/api/v1/time-entries/:id"}),e.jsx(s,{variant:"outline",className:"ml-auto text-xs",children:"API key required"}),e.jsx(s,{className:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 text-xs",children:"time_entries:write"})]}),e.jsx("p",{className:"text-sm text-gray-600 dark:text-gray-300 mb-6",children:"Update mutable fields on an existing time entry. Only fields included in the request body are changed — all others remain untouched. Supports attaching evidence to entries created earlier."}),e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-3",children:"Request body (JSON) — all fields optional"}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-left",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-gray-200 dark:border-gray-700",children:[e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Field"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500 pr-4",children:"Type"}),e.jsx("th",{className:"pb-2 text-xs font-semibold text-gray-500",children:"Description"})]})}),e.jsxs("tbody",{children:[e.jsx(a,{name:"propertyId",type:"number | null",description:"Assign or reassign property. Pass null to clear. Must belong to your workspace."}),e.jsx(a,{name:"description",type:"string",description:"Correct or enrich the activity description"}),e.jsx(a,{name:"hours",type:"number",description:"Adjust logged hours (min 0.001, max 24)"}),e.jsx(a,{name:"activityType",type:"string",description:"Reclassify the activity"}),e.jsx(a,{name:"evidence",type:"object | object[]",description:"Attach evidence — same schema as POST (base64 or URL)"})]})]})})]}),e.jsxs("div",{className:"p-6 bg-gray-50 dark:bg-gray-950",children:[e.jsx("h4",{className:"text-xs font-semibold text-gray-500 uppercase tracking-wider mb-4",children:"Response"}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(s,{className:"bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 text-xs",children:"200 OK"}),e.jsx("span",{className:"text-sm text-gray-500",children:"Updated time entry object"})]}),e.jsx("div",{className:"grid sm:grid-cols-3 gap-3 pt-2 text-sm",children:[["400","Validation error or property not found in workspace"],["401","Missing or invalid API key"],["403","Key lacks the time_entries:write scope"],["404","Time entry not found"],["500","Server error"]].map(([t,r])=>e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(s,{variant:"outline",className:"text-xs shrink-0",children:t}),e.jsx("span",{className:"text-gray-500 dark:text-gray-400",children:r})]},t))})]})]})]})]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-2",children:"Key management"}),e.jsx("p",{className:"text-gray-500 dark:text-gray-400 mb-6",children:"Session-authenticated endpoints (Settings → API Keys) and the agent-onboarding endpoint accessible via an existing API key."}),e.jsx("div",{className:"space-y-3",children:[{method:"GET",path:"/api/api-keys",desc:"List your active API keys (hashes are never returned)"},{method:"POST",path:"/api/api-keys",desc:"Create a new key — choose scopes; plaintext shown once and never stored"},{method:"POST",path:"/api/api-keys/:id/rotate",desc:"Atomically revoke a key and reissue a new one with the same name, scopes, and expiry"},{method:"DELETE",path:"/api/api-keys/:id",desc:"Revoke a key immediately and permanently"},{method:"POST",path:"/api/v1/auth/api-keys",desc:"Agent self-provisioning — create a new key programmatically using an existing API key"}].map(({method:t,path:r,desc:n})=>e.jsxs("div",{className:"flex items-center gap-3 p-4 rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx(c,{method:t}),e.jsx("code",{className:"font-mono text-sm text-gray-700 dark:text-gray-200",children:r}),e.jsx("span",{className:"ml-2 text-sm text-gray-500 dark:text-gray-400 hidden sm:block",children:n})]},r+t))}),e.jsxs("div",{className:"mt-6",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx(I,{className:"h-4 w-4 text-gray-400"}),e.jsx("span",{className:"text-sm font-semibold text-gray-700 dark:text-gray-300",children:"Agent self-provisioning example"})]}
207),e.jsx(d,{code:A,language:"typescript"}),e.jsxs("p",{className:"mt-3 text-sm text-gray-500 dark:text-gray-400",children:["The response body is identical to the regular create-key response: ",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded",children:"{ key: { id, name, scopes, expiresAt, plainKey } }"}),".",e.jsx("code",{className:"font-mono bg-gray-100 dark:bg-gray-800 px-1 rounded ml-1",children:"plainKey"})," is shown only once — store it immediately."]})]}),e.jsxs("div",{className:"mt-4 flex items-start gap-3 p-4 rounded-lg bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-800 text-sm text-gray-600 dark:text-gray-300",children:[e.jsx(F,{className:"h-4 w-4 mt-0.5 shrink-0 text-gray-400"}),e.jsxs("p",{children:[e.jsx("strong",{children:"Rotating a key"})," revokes the old key and issues a brand-new one in a single atomic operation. The new key preserves the same name, scopes, and expiry as the original — so your automation only needs to update the secret value."]})]})]}),e.jsxs("section",{children:[e.jsx("h2",{className:"text-2xl font-bold text-gray-900 dark:text-white mb-6",children:"Security best practices"}),e.jsx("div",{className:"grid sm:grid-cols-2 gap-4",children:[{icon:j,title:"Use environment variables",desc:"Never put your API key in source code or commit it to version control. Use a .env file or your tool's secret store."},{icon:m,title:"One key per tool",desc:"Name each key after the tool that uses it so you can revoke access for just that tool without affecting others."},{icon:R,title:"Rotate regularly",desc:"Create a new key and revoke the old one from time to time to limit exposure if a key is ever leaked."},{icon:y,title:"Set expiration",desc:"When creating a key you can supply an expiresAt date so it self-revokes after a certain period automatically."}].map(({icon:t,title:r,desc:n})=>e.jsxs("div",{className:"flex gap-4 p-5 rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900",children:[e.jsx("div",{className:"shrink-0 w-9 h-9 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center",children:e.jsx(t,{className:"h-4 w-4 text-green-700 dark:text-green-400"})}),e.jsxs("div",{children:[e.jsx("h3",{className:"font-semibold text-gray-900 dark:text-white text-sm mb-1",children:r}),e.jsx("p",{className:"text-sm text-gray-500 dark:text-gray-400",children:n})]})]},r))})]}),e.jsxs("section",{className:"rounded-2xl bg-gradient-to-br from-green-600 to-green-800 text-white p-8 sm:p-12 text-center",children:[e.jsx(I,{className:"h-10 w-10 mx-auto mb-4 opacity-80"}),e.jsx("h2",{className:"text-2xl sm:text-3xl font-bold mb-3",children:"Ready to automate your hours?"}),e.jsx("p",{className:"text-green-200 mb-6 max-w-md mx-auto",children:"Generate an API key from your account settings and have your first automated entry logged in minutes."}),e.jsx(k,{href:"/settings",children:e.jsxs(h,{size:"lg",className:"bg-white text-green-700 hover:bg-green-50 gap-2 font-semibold",children:["Go to Settings",e.jsx(_,{className:"h-4 w-4"})]})})]})]})]})}export{se as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.