@extends('layouts.app') @section('content')
Integración completa con tu sitio web mediante API RESTful
{{ config('app.url') }}/api/public
Las rutas públicas de la API no requieren autenticación. Para operaciones administrativas, se requiere token de autenticación.
Todas las respuestas se devuelven en formato JSON.
{
"success": true,
"data": { ... },
"message": "Operación exitosa"
}
200 - OK: Solicitud exitosa201 - Created: Recurso creado exitosamente400 - Bad Request: Error en los datos enviados404 - Not Found: Recurso no encontrado422 - Unprocessable Entity: Error de validación500 - Internal Server Error: Error del servidorEndpoint: GET /api/public/projects
Descripción: Obtiene la lista de proyectos activos disponibles para crear tickets.
fetch('{{ config('app.url') }}/api/public/projects', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => {
console.log('Proyectos:', data.data);
})
.catch(error => {
console.error('Error:', error);
});
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '{{ config('app.url') }}/api/public/projects');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$projects = json_decode($response, true);
print_r($projects['data']);
}
{
"success": true,
"data": [
{
"id": 1,
"name": "Sitio Web Corporativo",
"description": "Mantenimiento del sitio web principal",
"status": "activo"
},
{
"id": 2,
"name": "Aplicación Móvil",
"description": "Desarrollo de app móvil",
"status": "activo"
}
]
}
Endpoint: POST /api/public/tickets
Descripción: Crea un nuevo ticket desde un formulario público en tu sitio web.
| Campo | Tipo | Descripción |
|---|---|---|
title |
string | Título del ticket (mínimo 10 caracteres) |
description |
string | Descripción detallada del problema |
project_id |
integer | ID del proyecto (obtener de /api/public/projects) |
priority |
string | Prioridad: baja, media, alta, critica |
requester_email |
Email del solicitante |
const ticketData = {
title: 'Problema con el formulario de contacto',
description: 'El formulario de contacto no envía los correos correctamente...',
project_id: 1,
priority: 'alta',
requester_email: 'cliente@ejemplo.com'
};
fetch('{{ config('app.url') }}/api/public/tickets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(ticketData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('Ticket creado: ' + data.data.ticket_number);
} else {
alert('Error: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
});
$ticketData = [
'title' => 'Problema con el formulario de contacto',
'description' => 'El formulario de contacto no envía los correos correctamente...',
'project_id' => 1,
'priority' => 'alta',
'requester_email' => 'cliente@ejemplo.com'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '{{ config('app.url') }}/api/public/tickets');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($ticketData));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($response, true);
if ($httpCode === 201) {
echo "Ticket creado: " . $result['data']['ticket_number'];
} else {
echo "Error: " . $result['message'];
}
{
"success": true,
"message": "Ticket creado exitosamente",
"data": {
"id": 42,
"ticket_number": "TK2025100042",
"title": "Problema con el formulario de contacto",
"status": "abierto",
"priority": "alta",
"created_at": "2025-10-30T10:30:00.000000Z"
}
}
{
"success": false,
"message": "Error de validación",
"errors": {
"title": ["El título debe tener al menos 10 caracteres."],
"requester_email": ["El email no es válido."]
}
}
<!-- Formulario de Creación de Ticket -->
<form id="ticketForm">
<div class="mb-3">
<label for="project" class="form-label">Proyecto</label>
<select class="form-select" id="project" name="project_id" required>
<option value="">Seleccione un proyecto...</option>
</select>
</div>
<div class="mb-3">
<label for="title" class="form-label">Título</label>
<input type="text" class="form-control" id="title" name="title" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Descripción</label>
<textarea class="form-control" id="description" name="description" rows="4" required></textarea>
</div>
<div class="mb-3">
<label for="priority" class="form-label">Prioridad</label>
<select class="form-select" id="priority" name="priority" required>
<option value="baja">Baja</option>
<option value="media" selected>Media</option>
<option value="alta">Alta</option>
<option value="critica">Crítica</option>
</select>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="requester_email" required>
</div>
<button type="submit" class="btn btn-primary">Crear Ticket</button>
</form>
<script>
const API_BASE = '{{ config('app.url') }}/api/public';
// Cargar proyectos al inicio
fetch(`${API_BASE}/projects`)
.then(response => response.json())
.then(data => {
const select = document.getElementById('project');
data.data.forEach(project => {
const option = document.createElement('option');
option.value = project.id;
option.textContent = project.name;
select.appendChild(option);
});
});
// Manejar envío del formulario
document.getElementById('ticketForm').addEventListener('submit', function(e) {
e.preventDefault();
const formData = {
title: document.getElementById('title').value,
description: document.getElementById('description').value,
project_id: parseInt(document.getElementById('project').value),
priority: document.getElementById('priority').value,
requester_email: document.getElementById('email').value
};
fetch(`${API_BASE}/tickets`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('¡Ticket creado exitosamente! Número: ' + data.data.ticket_number);
document.getElementById('ticketForm').reset();
} else {
alert('Error: ' + data.message);
}
})
.catch(error => {
console.error('Error:', error);
alert('Ocurrió un error al crear el ticket');
});
});
</script>