diff --git a/src/NzbDrone.Api/Indexers/ReleasePushModule.cs b/src/NzbDrone.Api/Indexers/ReleasePushModule.cs
index e9e6da37f..61e5a760a 100644
--- a/src/NzbDrone.Api/Indexers/ReleasePushModule.cs
+++ b/src/NzbDrone.Api/Indexers/ReleasePushModule.cs
@@ -4,7 +4,6 @@ using FluentValidation;
 using Nancy;
 using Nancy.ModelBinding;
 using NLog;
-using NzbDrone.Api.Extensions;
 using NzbDrone.Common.Extensions;
 using NzbDrone.Core.Datastore;
 using NzbDrone.Core.DecisionEngine;
@@ -12,7 +11,7 @@ using NzbDrone.Core.Download;
 using NzbDrone.Core.Indexers;
 using NzbDrone.Core.Parser.Model;
 using Sonarr.Http.Extensions;
-using Sonarr.Http.Mapping;
+using Sonarr.Http.REST;
 
 namespace NzbDrone.Api.Indexers
 {
@@ -21,6 +20,7 @@ namespace NzbDrone.Api.Indexers
         private readonly IMakeDownloadDecision _downloadDecisionMaker;
         private readonly IProcessDownloadDecisions _downloadDecisionProcessor;
         private readonly IIndexerFactory _indexerFactory;
+        private ResourceValidator<ReleaseResource> _releaseValidator;
         private readonly Logger _logger;
 
         public ReleasePushModule(IMakeDownloadDecision downloadDecisionMaker,
@@ -35,14 +35,22 @@ namespace NzbDrone.Api.Indexers
 
             Post["/push"] = x => ProcessRelease(this.Bind<ReleaseResource>());
 
-            PostValidator.RuleFor(s => s.Title).NotEmpty();
-            PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
-            PostValidator.RuleFor(s => s.Protocol).NotEmpty();
-            PostValidator.RuleFor(s => s.PublishDate).NotEmpty();
+            _releaseValidator = new ResourceValidator<ReleaseResource>();
+            _releaseValidator.RuleFor(s => s.Title).NotEmpty();
+            _releaseValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
+            _releaseValidator.RuleFor(s => s.DownloadProtocol).NotEmpty();
+            _releaseValidator.RuleFor(s => s.PublishDate).NotEmpty();
         }
 
         private Response ProcessRelease(ReleaseResource release)
         {
+            var validationFailures = _releaseValidator.Validate(release).Errors;
+
+            if (validationFailures.Any())
+            {
+                throw new ValidationException(validationFailures);
+            }
+
             _logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl);
 
             var info = release.ToModel();
@@ -69,7 +77,7 @@ namespace NzbDrone.Api.Indexers
                 }
                 else
                 {
-                    _logger.Debug("Push Release {0} not associated with unknown indexer {1}.", release.Title, release.Indexer);
+                    _logger.Debug("Push Release {0} not associated with known indexer {1}.", release.Title, release.Indexer);
                 }
             }
             else if (release.IndexerId != 0 && release.Indexer.IsNullOrWhiteSpace())
@@ -82,7 +90,7 @@ namespace NzbDrone.Api.Indexers
                 }
                 catch (ModelNotFoundException)
                 {
-                    _logger.Debug("Push Release {0} not associated with unknown indexer {0}.", release.Title, release.IndexerId);
+                    _logger.Debug("Push Release {0} not associated with known indexer {0}.", release.Title, release.IndexerId);
                     release.IndexerId = 0;
                 }
             }
diff --git a/src/Sonarr.Api.V3/DiskSpace/DiskSpaceModule.cs b/src/Sonarr.Api.V3/DiskSpace/DiskSpaceModule.cs
index dedc59431..adf256a7c 100644
--- a/src/Sonarr.Api.V3/DiskSpace/DiskSpaceModule.cs
+++ b/src/Sonarr.Api.V3/DiskSpace/DiskSpaceModule.cs
@@ -4,12 +4,12 @@ using Sonarr.Http;
 
 namespace Sonarr.Api.V3.DiskSpace
 {
-    public class DiskSpaceModule :SonarrRestModule<DiskSpaceResource>
+    public class DiskSpaceModule : SonarrRestModule<DiskSpaceResource>
     {
         private readonly IDiskSpaceService _diskSpaceService;
 
         public DiskSpaceModule(IDiskSpaceService diskSpaceService)
-            :base("diskspace")
+            : base("diskspace")
         {
             _diskSpaceService = diskSpaceService;
             GetResourceAll = GetFreeSpace;
diff --git a/src/Sonarr.Api.V3/Indexers/ReleaseModule.cs b/src/Sonarr.Api.V3/Indexers/ReleaseModule.cs
index 78c7e6590..9777a185d 100644
--- a/src/Sonarr.Api.V3/Indexers/ReleaseModule.cs
+++ b/src/Sonarr.Api.V3/Indexers/ReleaseModule.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using FluentValidation;
 using Nancy;
 using Nancy.ModelBinding;
@@ -16,6 +17,7 @@ using NzbDrone.Core.Parser.Model;
 using NzbDrone.Core.Tv;
 using NzbDrone.Core.Validation;
 using Sonarr.Http.Extensions;
+using Sonarr.Http.REST;
 using HttpStatusCode = System.Net.HttpStatusCode;
 
 namespace Sonarr.Api.V3.Indexers
@@ -31,6 +33,7 @@ namespace Sonarr.Api.V3.Indexers
         private readonly IEpisodeService _episodeService;
         private readonly IParsingService _parsingService;
         private readonly Logger _logger;
+        private ResourceValidator<ReleaseResource> _releaseValidator;
 
         private readonly ICached<RemoteEpisode> _remoteEpisodeCache;
 
@@ -55,18 +58,26 @@ namespace Sonarr.Api.V3.Indexers
             _parsingService = parsingService;
             _logger = logger;
 
+            _releaseValidator = new ResourceValidator<ReleaseResource>();
+            _releaseValidator.RuleFor(s => s.DownloadAllowed).Equal(true);
+            _releaseValidator.RuleFor(s => s.IndexerId).ValidId();
+            _releaseValidator.RuleFor(s => s.Guid).NotEmpty();
+
             GetResourceAll = GetReleases;
             Post["/"] = x => DownloadRelease(this.Bind<ReleaseResource>());
 
-            PostValidator.RuleFor(s => s.DownloadAllowed).Equal(true);
-            PostValidator.RuleFor(s => s.IndexerId).ValidId();
-            PostValidator.RuleFor(s => s.Guid).NotEmpty();
-
             _remoteEpisodeCache = cacheManager.GetCache<RemoteEpisode>(GetType(), "remoteEpisodes");
         }
 
         private Response DownloadRelease(ReleaseResource release)
         {
+            var validationFailures = _releaseValidator.Validate(release).Errors;
+
+            if (validationFailures.Any())
+            {
+                throw new ValidationException(validationFailures);
+            }
+
             var remoteEpisode = _remoteEpisodeCache.Find(GetCacheKey(release));
 
             if (remoteEpisode == null)
diff --git a/src/Sonarr.Api.V3/Indexers/ReleasePushModule.cs b/src/Sonarr.Api.V3/Indexers/ReleasePushModule.cs
index 04a29c7f9..beef2f2d8 100644
--- a/src/Sonarr.Api.V3/Indexers/ReleasePushModule.cs
+++ b/src/Sonarr.Api.V3/Indexers/ReleasePushModule.cs
@@ -1,13 +1,18 @@
 using System.Collections.Generic;
 using System.Linq;
 using FluentValidation;
+using FluentValidation.Results;
 using Nancy;
 using Nancy.ModelBinding;
 using NLog;
+using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Datastore;
 using NzbDrone.Core.DecisionEngine;
 using NzbDrone.Core.Download;
+using NzbDrone.Core.Indexers;
 using NzbDrone.Core.Parser.Model;
 using Sonarr.Http.Extensions;
+using Sonarr.Http.REST;
 
 namespace Sonarr.Api.V3.Indexers
 {
@@ -15,36 +20,92 @@ namespace Sonarr.Api.V3.Indexers
     {
         private readonly IMakeDownloadDecision _downloadDecisionMaker;
         private readonly IProcessDownloadDecisions _downloadDecisionProcessor;
+        private readonly IIndexerFactory _indexerFactory;
+        private ResourceValidator<ReleaseResource> _releaseValidator;
         private readonly Logger _logger;
 
         public ReleasePushModule(IMakeDownloadDecision downloadDecisionMaker,
                                  IProcessDownloadDecisions downloadDecisionProcessor,
+                                 IIndexerFactory indexerFactory,
                                  Logger logger)
         {
             _downloadDecisionMaker = downloadDecisionMaker;
             _downloadDecisionProcessor = downloadDecisionProcessor;
+            _indexerFactory = indexerFactory;
             _logger = logger;
 
-            Post["/push"] = x => ProcessRelease(this.Bind<ReleaseResource>());
+            _releaseValidator = new ResourceValidator<ReleaseResource>();
+            _releaseValidator.RuleFor(s => s.Title).NotEmpty();
+            _releaseValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
+            _releaseValidator.RuleFor(s => s.DownloadProtocol).NotEmpty();
+            _releaseValidator.RuleFor(s => s.PublishDate).NotEmpty();
 
-            PostValidator.RuleFor(s => s.Title).NotEmpty();
-            PostValidator.RuleFor(s => s.DownloadUrl).NotEmpty();
-            PostValidator.RuleFor(s => s.DownloadProtocol).NotEmpty();
-            PostValidator.RuleFor(s => s.PublishDate).NotEmpty();
+            Post["/push"] = x => ProcessRelease(this.Bind<ReleaseResource>());
         }
 
         private Response ProcessRelease(ReleaseResource release)
         {
+            var validationFailures = _releaseValidator.Validate(release).Errors;
+
+            if (validationFailures.Any())
+            {
+                throw new ValidationException(validationFailures);
+            }
+
             _logger.Info("Release pushed: {0} - {1}", release.Title, release.DownloadUrl);
 
             var info = release.ToModel();
 
             info.Guid = "PUSH-" + info.DownloadUrl;
 
+            ResolveIndexer(info);
+
             var decisions = _downloadDecisionMaker.GetRssDecision(new List<ReleaseInfo> { info });
             _downloadDecisionProcessor.ProcessDecisions(decisions);
 
-            return MapDecisions(decisions).First().AsResponse();
+            var firstDecision = decisions.FirstOrDefault();
+
+            if (firstDecision?.RemoteEpisode.ParsedEpisodeInfo == null)
+            {
+                throw new ValidationException(new List<ValidationFailure>{ new ValidationFailure("Title", "Unable to parse", release.Title) });
+            }
+
+            return MapDecisions(new [] { firstDecision }).AsResponse();
+        }
+
+        private void ResolveIndexer(ReleaseInfo release)
+        {
+            if (release.IndexerId == 0 && release.Indexer.IsNotNullOrWhiteSpace())
+            {
+                var indexer = _indexerFactory.All().FirstOrDefault(v => v.Name == release.Indexer);
+                if (indexer != null)
+                {
+                    release.IndexerId = indexer.Id;
+                    _logger.Debug("Push Release {0} associated with indexer {1} - {2}.", release.Title, release.IndexerId, release.Indexer);
+                }
+                else
+                {
+                    _logger.Debug("Push Release {0} not associated with known indexer {1}.", release.Title, release.Indexer);
+                }
+            }
+            else if (release.IndexerId != 0 && release.Indexer.IsNullOrWhiteSpace())
+            {
+                try
+                {
+                    var indexer = _indexerFactory.Get(release.IndexerId);
+                    release.Indexer = indexer.Name;
+                    _logger.Debug("Push Release {0} associated with indexer {1} - {2}.", release.Title, release.IndexerId, release.Indexer);
+                }
+                catch (ModelNotFoundException)
+                {
+                    _logger.Debug("Push Release {0} not associated with known indexer {0}.", release.Title, release.IndexerId);
+                    release.IndexerId = 0;
+                }
+            }
+            else
+            {
+                _logger.Debug("Push Release {0} not associated with an indexer.", release.Title);
+            }
         }
     }
 }